[Fixed]-Docker compose for production and development


You should create additional docker-compose.yml files like docker-compose-dev.yml or docker-compose-pro.yml and override some of the original docker-compose.yml configuration with -f command:

docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -d

Sometimes, I also use different Dockerfile for different environments and specify dockerfile parameter in docker-compose-pro.yml build section, but I didn’t recommend it because you will end with duplicated Dockerfiles.


Docker has introduced multi-stage builds feature https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds which allow to create a Dockerfile for different environments.



Docker Compose can build out a production environment or development environment depending on what the .env file says.

The build: directive for each service in your compose.yaml file allows you to specify the Dockerfile used to build out the service. Use dockerfile:${nginx_Prod_Dockerfile}, for example. You will need two Dockerfile‘s for each service – one dev, the other prod.

This allows you to utilize the same compose.yaml to build both environments depending on what your .env file says.

See the documentation


Substitute with –env-file

You can set default values for multiple environment variables, in an environment file and then pass the file
as an argument in the CLI.

The advantage of this method is that you can store the file anywhere
and name it appropriately, for example, .env.ci, .env.dev, .env.prod.
This file path is relative to the current working directory where the
Docker Compose command is executed. Passing the file path is done
using the –env-file option:

docker compose --env-file ./config/.env.dev up


Usually having a different production and dev starting workflow is a bad idea. You should always try to keep both dev and prod environments very similar, even in the way you launch your applications. You should always externalize the configuration that is different between the different environments.

Having different startup sequence is maybe acceptable, however having multiple docker images (or dockerfiles) for each environment is a very bad idea. Docker images should be immutable and portable.

However, you might have some constraints. Docker-compose allows you to override the command that is specified in the image. There is the command property that will override the default command in the image. I would recommend that you keep the image production ready,
i.e. use something like CMD ./manage.py collectstatic && ./manage.py migrate && uwsgi --http -w wsgi --processes=4 in the Dockerfile.

In the compose file just override the CMD by specifying:

command: ./manage.py runserver 

Having multiple compose file is usually not a big issue. You can keep your compose files clean and manageable by using some nice compose file features such as extends, where once compose file can extend another one.


Leave a comment