Docker Tip #93: Remove the env_file Property from Postgres and Redis
You can almost cut your app's Docker Compose recreate containers time in half by avoiding needless recreates on .env changes.
Prefer video? Here’s a recorded version of this tip on YouTube.
It’s very common to have something like this defined in your
docker-compose.yml
file:
services:
myapp:
env_file:
- ".env"
This way you can have your environment variables defined in a single .env
file.
It’s also very common to re-use that .env
file in other containers like this:
services:
postgres:
env_file:
- ".env"
redis:
env_file:
- ".env"
This is especially true with Postgres where you need to define at least a
POSTGRES_USER
and POSTGRES_PASSWORD
for the container to start. It makes
sense to drop those in a .env
file so you may have blindly copy / pasted your
env_file
reference to all of your containers because “why not?” (I know I did
for a while).
In Docker Tip #90 I went
over how docker compose up
works around recreating containers based on what
changes which does include .env
values.
If you used the above set up then every time you changed one of your app’s
.env
variables (such as an unrelated Stripe API key) then Postgres and Redis
will get recreated!
You can avoid that by removing env_file
from both services or more generally
any service where you don’t want to needlessly recreate them on all .env
var
changes.
You can securely insert your POSTGRES_USER
and POSTGRES_PASSWORD
variables
into Postgres like this:
services:
postgres:
environment:
POSTGRES_USER: "${POSTGRES_USER}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
# POSTGRES_DB: "${POSTGRES_DB}"
It will read these values from your .env
file thanks to Docker Compose
supporting variable interpolation, which I covered in my DockerCon 21
talk btw.
All of my example Docker web
apps use this
pattern. It dropped my docker compose up -d
time from ~5.5 seconds down to
about 3.5 seconds for .env
changes.