I'm trying to wrap my head around Docker, but I'm having a hard time figuring it out. I tried to implement it in my small project (MERN stack), and I was thinking how do you distinct between development, (maybe staging), and production environments.
I saw one example where they used 2 Docker files, and 2 docker-compose files, (each pair for one env, so Dockerfile + docker-compose.yml for prod, Dockerfile-dev + docker-compose-dev.yml for dev).
But this just seems like a bit of an overkill for me. I would prefer to have it only in two files.
Also one of the problem is that e.g. for development I want to install nodemon globally, but not for poduction.
In perfect solution I imagine running something like that
docker-compose -e ENV=dev build docker-compose -e ENV=dev up
Keep in mind, that I still don't fully get docker, so if you caught some of mine misconceptions about docker, you can point them out.
It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.
Let's say we have two Dockerfiles, one for building the backend and another for building the frontend. We can name them appropriately and invoke the build command two times, each time passing the name of one of the Dockerfiles: $ docker build -f Dockerfile.
Using Multiple Docker Compose Files Use multiple Docker Compose files when you want to change your app for different environments (e.g., dev, staging, and production) or when you want to run admin tasks against a Compose application.
In your Dockerfile , you can use the verb EXPOSE to expose multiple ports.
You could take some clues from "Using Compose in production"
You’ll almost certainly want to make changes to your app configuration that are more appropriate to a live environment. These changes may include:
- Removing any volume bindings for application code, so that code stays inside the container and can’t be changed from outside
- Binding to different ports on the host
- Setting environment variables differently (e.g., to decrease the verbosity of logging, or to enable email sending)
- Specifying a restart policy (e.g., restart: always) to avoid downtime
- Adding extra services (e.g., a log aggregator)
The advice is then not quite similar to the example you mention:
For this reason, you’ll probably want to define an additional Compose file, say
production.yml
, which specifies production-appropriate configuration. This configuration file only needs to include the changes you’d like to make from the original Compose file.docker-compose -f docker-compose.yml -f production.yml up -d
This overriding mechanism is better than trying to mix dev and prod logic in one compose file, with environment variable to try and select one.
Note: If you name your second dockerfile docker-compose.override.yml
, a simple docker-compose up
would read the overrides automatically.
But in your case, a name based on the environment is clearer.
Docker Compose will read docker-compose.yml
and docker-compose.override.yml
by default. Understanding-Multiple-Compose-Files
You can set a default docker-compose.yml
and different overwrite compose file. For example, docker-compose.prod.yml
docker-compose.test.yml
. Keep them in the same place.
Then create a symbolic link named docker-compose.override.yml
for each env.
Track docker-compose.{env}.yml
files and add docker-compose.override.yml
to .gitignore
.
In prod env: ln -s ./docker-compose.prod.yml ./docker-compose.override.yml
In test env: ln -s ./docker-compose.test.yml ./docker-compose.override.yml
The project structure will then look like this:
project\ - docker-compose.yml # tracked - docker-compose.prod.yml # tracked - docker-compose.test.yml # tracked - docker-compose.override.yml # ignored & linked to override composefile for current env - src/ - ...
Then you have done. In each environment, you can use the compose-file with the same command docker-compose up
If you are not sure, use docker-compose config
to check if it's been override properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With