DEV Community

Tom VanAntwerp
Tom VanAntwerp

Posted on

Don't Quote Environment Variables in Docker

It's usually a good idea to store your app's environment variables separate from the app itself in a .env file. This allows you to easily have different values for development, staging, and production.

Normally when writing a .env file, you might have an unusual property like an API key that has lots of special characters. Typically you would quote this value to handle that.

# a normal environment variable, surrounded by single quotes
KEY='example bl4h 5tuFF 123@#%= ksjhbfdg'
Enter fullscreen mode Exit fullscreen mode

Your system would know to treat what's inside the single quotes as the value of KEY and make it available to your app.

But Docker doesn't work this way.

Let's say you're passing a .env file into a Docker container via docker-compose.yml. Docker would interpret the quotes around the environment variables as part of the value itself!

For a real world example, here's an environment variable passed to the official WordPress Docker image and the resulting output in the container's wp-config.php file (value is random and not used for anything, obviously):

# environment variable in a .env file
WORDPRESS_DB_PASSWORD='Pr65s$CWv{P3k}4j6]I<j=U5n#keN&$D{{Uhv2@L'
Enter fullscreen mode Exit fullscreen mode
// output to wp-config.php
// notice the escaped \' at the beginning and end
define( 'DB_PASSWORD', '\'Pr65s$CWv{P3k}4j6]I<j=U5n#keN&$D{{Uhv2@L\'');
Enter fullscreen mode Exit fullscreen mode

The database password in wp-config.php would be incorrect because Docker considered the single quotes as part of the key value!

So as weird and wrong as it appears, when using .env files with Docker, don't quote values! The above example done correctly would then look like this:

# environment variable in a .env file
WORDPRESS_DB_PASSWORD=Pr65s$CWv{P3k}4j6]I<j=U5n#keN&$D{{Uhv2@L
Enter fullscreen mode Exit fullscreen mode
// output to wp-config.php
define( 'DB_PASSWORD', 'Pr65s$CWv{P3k}4j6]I<j=U5n#keN&$D{{Uhv2@L');
Enter fullscreen mode Exit fullscreen mode

Latest comments (4)

Collapse
 
sammck profile image
Sam McKelvie

This article is out-of date. At some point (~v1.28), docker-compose switched to using dotenv to parse the environment files. Single and double-quoted strings are parsed specially. single-quoted strings can be multiline. Double-quoted strings can have escapes such as "\n" to produce multi-line values.

Collapse
 
ricoms profile image
Ricardo Manhães Savii

it's not outdate. I've ran into this problem today and I'm using Docker version 20.10.23, with node 18 and typescript. And, it took me too much time to find this post. Thanks OP

Collapse
 
mscott profile image
Michael

It made me realize my docker version was way too old.

Collapse
 
ivankleshnin profile image
Ivan Kleshnin • Edited

The article is not outdated for peoople who use Docker Swarm. Its still behaves incorrectly:

JWT_SECRET='{"type": "HS256", "key": "xxx"}'
Enter fullscreen mode Exit fullscreen mode

$ docker compose up ... with .env_file

[container] $ echo $JWT_SECRET
{"type": "HS256", "key": "xxx"}
Enter fullscreen mode Exit fullscreen mode

$ docker stack deploy ... with .env_file

[container] $ echo $JWT_SECRET
'{"type": "HS256", "key": "xxx"}'
Enter fullscreen mode Exit fullscreen mode

So if you're going to use Swarm mode you should... avoid quotes and spaces in JSON values and define them like:

JWT_SECRET={"type":"HS256","key":"xxx"}
Enter fullscreen mode Exit fullscreen mode