-3

Is there any proper way of restarting an entire docker compose stack from within one of its containers?

One workaround involves mounting the docker socket:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock

and then use the Docker Engine SDKs (https://docs.docker.com/engine/api/sdk/examples/).

However, this solution only allows restarting the containers itselves. There seems to be no way to send compose commands, like docker compose restart, docker compose up, etc.

The only solution I've found to send docker compose commands is to open a terminal on the host from the container using ssh, like this: access host's ssh tunnel from docker container

This is partly related to How to run shell script on host from docker container? , but I'm actually looking for a more specific solution to only send docker compose commands.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Trenomarcus
  • 172
  • 7
  • 1
    If you have docker and docker compose installed in the container, you should be able to do what you want by mapping the socket. – Hans Kilian Sep 18 '22 at 10:03
  • 1
    `There seems to be no way to send compose commands, like docker compose restart, docker compose up` ? Why? What happens if you do? There is a way, just execute them, the same way. – KamilCuk Sep 18 '22 at 10:08
  • 1
    ...and if you do make the Docker socket available as @HansKilian suggests, it gives the container unrestricted root-level access over the entire host system. (Without Docker, the application rebooting the host would accomplish this; do you want that capability?) Unless you're trying to write some sort of remote-administration tool (and then I'd separate it from the application) I'd suggest just skipping over this capability. – David Maze Sep 18 '22 at 10:42
  • `If you have docker and docker compose installed in the container, you should be able to do what you want by mapping the socket.` As I've mentioned, restarting containers is definitely possible by mapping the socket. Using docker compose commands however requires the `docker-compose.yml` file inside the container itself, and even if I map the file from the host to the container, the commands get executed inside the container, which is not what I'm trying to achieve (I need them executed on the host). In fact, docker compose sees no services running inside the container (obviously). – Trenomarcus Sep 18 '22 at 11:23
  • 1
    Why doesn't compose see the services? You say "obviously" but it's not obvious unless you are connecting to a different engine? My suspicion is you have set a different compose project name (or changed the directory name inside the container which has the same effect). – BMitch Sep 18 '22 at 12:00
  • The best advice you're getting here is from David. If you aren't building a management service that can be separate from the application, then you're creating a significant security risk. This would be better done by the application itself. Maybe a trigger file shared by a volume that the containers see has a newer date than their start time that triggers an exit. – BMitch Sep 18 '22 at 12:03
  • `My suspicion is you have set a different compose project name (or changed the directory name inside the container which has the same effect). ` That's the answer. Updating OP. – Trenomarcus Sep 18 '22 at 12:29

2 Answers2

0

I tried with this simple docker-compose.yml file

version: '3'
services:
  nginx:
    image: nginx
    ports:
      - 3000:80

Then I started a docker container using

docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/work docker

Then, inside the container, I did

cd /work
docker-compose up -d

and it started the container up on the host.

Please note that you have an error in your socket mapping. It needs to be

- /var/run/docker.sock:/var/run/docker.sock

(you have a period instead of a slash at one point)

Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • Ok so by running the container using docker, NOT docker-compose, and then running `docker-compose up` inside, it works. However, if I try to restart the stack from inside the container, `docker-compose restart` I get: ```ERROR: No containers to restart ``` cause docker-compose does not see the running services on the host. – Trenomarcus Sep 18 '22 at 12:23
  • It's kind of hard to know why you're getting errors, when all you've shown of your setup is a single line of a docker-compose file. – Hans Kilian Sep 18 '22 at 12:24
  • Try `docker-compose restart` inside the container :) Just to be clear, `docker restart` works fine. – Trenomarcus Sep 18 '22 at 12:26
  • project-name was the reason, thanks for your example anyway :) – Trenomarcus Sep 18 '22 at 12:29
0

As mentioned by @BMitch in the comments, compose project name was the reason why I wasn't able to run docker compose commands inside the running container.

By default the compose project name is set to the directory name, so if the docker-compose.yml is run from a host directory named folder1, then the commands inside the container should be run as:

docker-compose -p folder1 ...

So now, for example, restarting the stack works:

docker-compose -p folder1 restart

Just as a reference, a fixed project name for your compose can be set using name: ... as a top-level attribute of the .yml file, but requires docker compose v2.3.3 : Set $PROJECT_NAME in docker-compose file

Trenomarcus
  • 172
  • 7