with docker-compose there is a command / argument like „depends_on“ to define dependencies of multiple containers. Is there a similar option for Docker run? I haven’t found anything on the net right now, only detailed information about using docker-compose.
My use case is about creation of a dependency for Telegraf and InfluxDB running as separate containers.
My use case is about having several containers writing to the same InfluxDB container database, is this possible in general?
Currently I am using (but I am not sure if this is the best way).
docker run -d \
--name telegraf \
-v /opt/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf \
-v /var/run/docker.sock:/var/run/docker.sock \
--user telegraf:$(stat -c '%g' /var/run/docker.sock) \
When to use “net”, when to use “link”, (to come back to my initial question: when to use “depends_on”)
d) (maybe a silly question)
When using the “net” argument:
Does the influxdb container need to have the same structure, also having the argument “net” like e.g.
No. How would that work? In a Docker Compose file you can define the parameters of all containers. Then you can define dependencies, but without compose, you don’t have the definitions of the containers. You could implement in a shell script, but why would you do that instead of using Docker Compose which was designed to do that. On the other hand, a dependency is just the order of running the docker run commands, so you can have a simple script with multiple docker run after eachother. Still, I would use Docker Compose.
Of course. What is the reason of your doubt?
This is not dependency. Docker has no way to know how you wnt to run influxdb, so you need to run that first and run telegraf with the
--net parameter to use the same loopback network interface (localhost) as influxdb.
I wrote about net, but link is similar. It will not start the dependency and link is actually a deprecated option. You should use user-defined networks. While net is to choose which network you want to attach to the container, link is allow the new container (the one that uses the link option) to use a hostname to access an other container. This works without links when you are using user-defined networks and you can use the container name as hostname. Whe you are using Docker Compose, you can also use the service name as hostname.
When it is important to start a container before an other. Just a simple example. Imagine that you have two services in a Docker Compose file. Both of them are using the same volume. Let’s call it just “data”. If you mount that volume into both containers, the fist container that starts will mount the volume and copy the content of the mount point to the host so the other container can see the same content. Let’s say these two containers are “php” and “httpd” and your application code is in the “php” container. If httpd starts first, it could initialize the volume and “php” would mount for example a single
index.html over the application code.
Not only no, but you can’t do that. By default each container will have its own loopback network interface. (“localhost”). Using
--net container:containernamemeans that the container will not have its own, but it will use the “localhost” of an other.
thank you (once again! ) for your detailed feedback, the time invested in your response and the quick help.
I appreciate your support very much.
For some projects I will now use docker-compose instead docker run - especially if containers have dependencies. I already tried in former times a few things with docker-compose but somehow docker run was feeling kind of more comfortable to me.
In parallel I will go in deep dives regarding the user-defined networks you mentioned.
…well…In the beginning, I really only wanted to test docker to have a say (as I preferred virtual machines at that time) - but in the meantime I want to use docker for everything …Therefore, such “beginner-compatible” explanations as these ones from you are all the more helpful. Thank you again for that.
Two more question was coming into my mind:
- Using docker-compose, do I have to build all containers at once or is it possible to create a “depends_on” to an already running container?
- I have an InfluxDB container running already
- When creation of the docker-compose for Telegraf and Grafana (both in the same docker-compose file), is there any way to make a dependency on the InfluxDB container? Or do I have to create a docker-compose file containing Telegraf, Grafana and InfluxDB?
- Having an *.env file, can the same file be used for more services (e.g. InfluxDB and Grafana in configuration.env) or do I need to have a separate *.env file for each service (e.g. influxdb_config.env and grafana_config.env)?
Thanks again for your quick reply.
I take it as “good practise” then to use different *.env configurations (especially with regard to the security topics you mentioned or in the case of having different containers being affected with a change of the *.env file).
So I started my InfluxDB with Docker run first
docker run -d \
-p 8086:8086 \
-v /opt/influxdb/data:/var/lib/influxdb2 \
-v /opt/influxdb/config:/etc/influxdb2 \
-v /etc/localtime:/etc/localtime:ro \
-e TZ=Europe/Berlin \
--restart unless-stopped \
and tried to add e.g. Telegraf via
docker-compose -d (see below)
but this does not seem to work:
sudo docker-compose up -d
ERROR: Service 'telegraf' depends on service 'influxdb' which is undefined.
How can I define it in my docker-compose file? Pointing to a service which is a) already running and b) has no detailed part of the docker-compose service definition (see above)
Or you can use one
*.env) which is automatically read by Docker Compose. These variables would not be addedd the the services as environment variables, but you can refer to these variables in the yaml:
Why would you even do that? When I wrote you can add new services I meant you can create a compose file with one service and later add new services depending on the already added service.
depends_on is for services in the compose file so you can make sure when you start service B which depends on service A, then service A will start too before the other.
If you have a running container which is not a compose service that is like any other service on any remote machine that you want to be running before starting the new service. You can’t controll that. What you can do is creating a n entrypoint or a start command that waits for a TCP connection for example or anything that you can check.
Even if you use
depends_on with the short syntax as you did, it will only depend on starting the other container not the application inside that contaier. If you want to change that, you can use healthchecks nd the long syntax of depends_on
Note that I linked the compose specification which is for Docker Compose v2. This is why I used
docker compose command instead of
Thanks again and 5 stars to you for providing such a beginner friendly explanation.
Now I got your point. So I can run docker compose (no “-”) to have v2 instead of v1 and when I add a service to the docker compose file I can just execute the command once again.
This information is also really helpful.
Yes, but this is not a feature of v2. It was always true. v2 is just the latest compose which works as a docker cli plugin. Docker Desktop contains it, but you need to install
docker-compose-plugin on Linux host or download the binary from GitHub.
This time I have done something already before I started this topic here
docker-compose-plugin is already the newest version (2.12.2~debian-bullseye)