Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker multiple environments

Tags:

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.

like image 477
maciejmatu Avatar asked Feb 17 '17 00:02

maciejmatu


People also ask

Can a Docker container have multiple services?

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.

Can we have 2 Docker files?

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.

Can I have multiple Docker compose files?

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.

Can I expose multiple ports Docker?

In your Dockerfile , you can use the verb EXPOSE to expose multiple ports.


2 Answers

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.

like image 90
VonC Avatar answered Sep 20 '22 06:09

VonC


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.

like image 30
kehao Avatar answered Sep 24 '22 06:09

kehao