docker_logo.png

In the previous article I looked at running and managing multiple containers (sites) using a single docker file. The next task is separate variables for different sites in the env file. For example, in the previous article the PROJECT_NAME environment variable was passed to the docker-compose file. It would be good if the variables were stored in separate files for each site.

For example. We have two sites website1 and website2. There is a common file .env and custom .Website1.env and .Website2.env.

Let's look at the .Website1.env file

PROJECT_NAME=Website1
PROJECT_WEB=website1
PROJECT_PHP=php56
PROJECT_DRUPAL=drupal7

PROJECT_NAME – will be used for the container name and for linking sections. In this example, the Website1 site files are located in the folder of the same name.
PROJECT_WEB – is used for the site name in the URL for traffic.
PROJECT_PHP – the ability to use different PHP versions for sites.
PROJECT_DRUPAL – this variable will allow you to select the desired docker-compose file for the site.

Sites are managed from the docker-center folder. In which all the configs are located. Thus, we can store configs in one directory and in a separate repository, respectively.

Let's consider the command from the Makefile file to launch containers for Website1.

#!make

include .env

DOCKER_DIR = $(shell pwd)

network:
    ${DOCKER_DIR}/network.sh

up-traefik:
    docker-compose --project-name rt-traefik --file ${DOCKER_DIR}/docker-compose.traefik.yml up -d --build


up-%: up-traefik
    @bash -c ' \
        set -o allexport; \
        source .${$(*)}.env; \
        set +o allexport; \
        docker-compose --project-name ${$(*)} --file ${DOCKER_DIR}/docker-compose.$${PROJECT_DRUPAL}.yml up -d --build; \
    '

declare a new variable to store the current DOCKER_DIR folder.

The up-% command is run with a parameter.

Loading variables from a file is done with the set command in bash. To do this, we wrap the entire command under bash. @ before bash means running the command without displaying it on the screen.

The parameter that we passed through the % symbol is stored in $(*). But, at the beginning of the makefile, we load our usual .env, where aliases for sites are defined

website1=Website1
w1=${website1}

thus, running the command up-website1 we get from ${$(*)} - Website1.

Same thing with up-w1! The alias is created for convenience.

And now our command source .${$(*)}.env; after dereferencing will look like source .Website1.env;

And all variables will be loaded from it.

In the line

docker-compose --project-name ${$(*)} --file ${DOCKER_DIR}/docker-compose.$${PROJECT_DRUPAL}.yml up -d --build; \

we get the PROJECT_DRUPAL variable from the .Website1.env file using $${PROJECT_DRUPAL}

All loaded variables from .Website1.env will be available in docker-compose file. And we will be able to do something like

build:
   context: images-drupal7/${PROJECT_PHP}

Where each version of PHP can have its own settings, etc.

This approach is also useful for overwriting configs through the settings.local.php files, where it will be different for different versions of Drupal.

Now we launch everything

$ ./network.sh
$ make up-w1 up-w2

Let's look at the traefik admin panel http://127.0.0.1:8080/dashboard/#/http/routers

We go by URLs

http://website1.my-docker.localhost/

http://website2.my-docker.localhost/

And we see that the sites work perfectly.

To stop, we write

$ make stop-w1 stop-w2

This way you can instantly launch the required site with one command with all the necessary configs.

Sources at the link: https://github.com/onesixromcom/docker_makefile_env_load

In this version, the container with the base was removed to speed up the launch. You will have it, of course.

PS: I agree, such copy-pasta of bash commands is an eyesore. But I haven't had time to figure it out yet. Alternatively, you can throw this into a sh file and pass additional commands to it after initializing the variables. But another time.