Search code examples
pythondockerenvironment-variables

When reading environment variables in Python from Docker's --env-file argument, there is an added '\' to each '\n'. How to not have that extra '\'?


I'm in the process of containerizing my Python app. Normally, I'd load in my .env file and use dotenv to read in the variable.

Example:

from dotenv import load_dotenv
import os


def test_env():
    load_dotenv()
    print(f"private_key : {repr(os.environ.get('PRIVATE_KEY'))}")


if __name__ == '__main__':
    test_env()

and in my .env file I'd have to have quotes around my variable for this to work too. Example:

PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n.....=\n-----END PRIVATE KEY-----\n"

This gets printed out correctly in my Python application.

However, when I run the same code but using Docker's --env-file I get an extra \ added to each \n.

Example docker command:

docker run --env-file ./.env -d -p $(RUN_PORT):$(RUN_PORT) --name $(DOCKER_CONTAINER_NAME) $(FULL_IMG_NAME)

The output looks like: '-----BEGIN PRIVATE KEY-----\\n...=\\n-----END PRIVATE KEY-----\\n' This is regardless of whether the .env file has "" around the variable or not. All the "" does to the variable, is that literal to the variable, which is not the case with dotenv.

What needs to be done?


Solution

  • dotenv processes the text and decodes escape sequences. So it replaces \n with a newline character.

    os.environ.get doesn't, so your string contains two characters: a backslash and an 'n'. The repr function then escapes the backslash when you print it, so you get the double backslash you see.

    You can process the escape sequences yourself in Python using the decode function like this

    import os
    
    def test_env():
        private_key = bytes(os.environ.get('PRIVATE_KEY'), "utf-8").decode("unicode_escape")
        print(f"private_key : {repr(private_key)}")
    
    if __name__ == '__main__':
        test_env()
    

    That should read the private key from the environment variable and change \n to newlines like you're used to dotenv doing.