R
R
Ruslan Mustaev2020-03-05 12:27:21
Docker
Ruslan Mustaev, 2020-03-05 12:27:21

Docker-compose how to correctly set the order of creating and running containers?

Good day dear ones.
Tell me how to correctly set the order of build and launch of containers using docker-compose?
The task following and a problem with it.
In the process of creating containers, namely PostgreSQL, php-fpm, nginx, there is also a need to run Composer which starts downloading the modules it needs, as well as NodeJS with its NPM which also pulls modules.
All this is added to one Volume in different folders, and after the Composer download is completed, the database migration is also launched, which looks into the file that the Composer downloaded. After downloading the modules, NPM starts building them.
The problem is the following:
In the docker compose file, I specify that the first thing to do is to launch the container with the composer that starts downloading files, but I can’t execute the command to start the database migration because the docker thinks everything is ok, it started everything, the container is working, it’s time to continue building and running next, or perform the next RUN, but in fact the files are not immediately downloaded, it takes time, and on a large project it takes up to 5 minutes and depends heavily on the size of the channel on the hardware where it all starts. Those. there is no possibility, for example, to set a slip to wait for the download to complete and then continue to complete the stages.
The same applies to NPM, it also starts, downloads, but there is no way to execute the build because everything has not yet been downloaded, and the docker thinks that everything is OK, the container is running.
Played with
depends_on:
- composer
and tried to sort in different ways, damn it, docker thinks that the container is running and everything is OK, but yes, it is running, downloading, after the download is complete, it extinguishes it and either raises the container with an external script and sends it a command to execute the build or migration in the case of the database, but I would like to try to solve everything using docker tools.
Can anyone point me in the right direction? How to track at least when the container has finished working and use it as an event to run an external script for the build? I thought about a multistage build, but so far I don’t fully understand how it works, and how it can be decided there with what the docker does while the files are downloading, I don’t think that this will drastically help.

If the questions are stupid, do not judge strictly, I'm just in the process of learning docker.

Thank you all in advance.

update.

I decided to add a little to complete the picture.
Initially, the folder where the composer downloads is empty, the list of what needs to be downloaded is in the composer.json file, the
folder where NPM downloads is also empty, everything that needs to be said in it lies in the package.json file
After everything that is listed in these files is downloaded to volume, you can already run the following steps.
the composer.json and package.json files can change and the composition of what needs to be downloaded can also change.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
S
Sergey Sokolov, 2020-03-05
@sergiks

If I understand correctly, now it's done so that composer starts its business in a running container, and not in the build process - creating the container itself.
It seems that the solution would be to create your own image based on the composer image, and swap files during the build process. And run it already built.
In a subfolder ./Composercreate a Dockerfile with something like this:

FROM composer:latest
VOLUME ./data  /data
RUN apt-get update && apt-get install git && git pull trololo && composer install

And in docker-compose.yml
services:
  composer:
    build: ./Composer

So while the image is being built, doing everything in the Dockerfile, it is not considered running, and the depends_onfollowing services dependent on it ( ) do not start.

K
k0nart, 2020-03-07
@k0nart

Look towards https://github.com/jwilder/dockerize . He knows how to wait for dependencies to be ready, works with various punctures, incl. file/, you can wait until file X appears on the docker and then start building the second one. (well, or by analogy with other protocols, whichever is more convenient)

V
Vladimir Kuts, 2020-03-05
@fox_12

The easiest option:
In the script for starting services in the container, do something like this:

touch /somedir/someflag
... # какая-то продолжительная последовательность инициализации
rm -f /somedir/someflag # это выполнить по успешному окончанию

In another container that depends on the results of the previous container:
sleep 5   # подождать немного пока основной контейнер инициализируется
while [ -f /somedir/someflag ];
do 
    sleep 1
    echo 'Waiting for container x'
done;
... # старт сервисов зависимого контейнера

The /somedir/ folder should be visible to both containers

R
Ruslan Mustaev, 2020-03-28
@NorthFighter

In the process of solving the problem above, I encountered the need to place the main workdir in the directory above the location of the dockercompos file and next to the folders with dockerfiles.
I ran into a problem with a misunderstanding of the paths.
I have a script that clones the project into a folder, and then the script runs a docker compose that uses the directory path to the leaning project in the file.
The project itself is a couple of folders up in the directory relative to the dockercompose file.
In general, during the execution process, the dockercompos swears that the path must be relative and that, as I understand it, constructions like ./../project_app do not work.
Will I have to set values ​​through ENV?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question