Is it possible to start a stopped container from another container

Solution 1:

It is possible to grant a container access to docker so that it can spawn other containers on your host. You do this by exposing the docker socket inside the container, e.g:

docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...

Now, if you have the docker client available inside the container, you will be able to control the docker daemon on your host and use that to spawn your "container A".

Before trying this approach, you should be aware of the security considerations: access to docker is the same as having root access on the host, which means if your web application has a remote compromise you have just handed the keys to your host to the attackers. This is described more fully in this article.

Solution 2:

It is possible by mounting the docker socket.

Container A
It will print the time to the stdout (and its logs) and exit.

docker run --name contA ubuntu date

Container B
The trick is to mount the host's docker socket then install the docker client on the container. It will then interact with the daemon just as if you were using docker from the host. Once docker is installed, it simply restart container A every 5 seconds.

docker run --name contB -v /var/run/docker.sock:/var/run/docker.sock ubuntu bash -c "
apt-get update && apt-get install -y curl &&
curl -sSL https://get.docker.com/ | sh && 
watch --interval 5 docker restart contA"

You can see that contA is being called by looking at its logs

docker logs contA

That said, Docker is really meant for long running services. There's some talk over at the Docker github issues about specifying short lived "job" services for things like maintenance, cron jobs, etc, but nothing has been decided, much less coded. So it's best to build your system so that containers are up and stay up.

Solution 3:

docker-compose.yml (credits to larsks)

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

Dockerfile (credits to Aaron V)

# ...

ENV DOCKERVERSION=19.03.12
RUN curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz \
  && tar xzvf docker-${DOCKERVERSION}.tgz --strip 1 -C /usr/local/bin docker/docker \
  && rm docker-${DOCKERVERSION}.tgz

# ...

Node.js index.js (credits to Arpan Abhishek, Maulik Parmar and anishsane)

# ...

const { exec } = require("child_process");

# ...

        exec('docker container ls -a --format "table {{.ID}}\t{{.Names}}" | grep <PART_OF_YOUR_CONTAINER_NAME> | cut -d" " -f1 | cut -f1 | xargs -I{} docker container restart -t 0 {}', (error, stdout, stderr) => {
            if (error) {
                console.log(`error: ${error.message}`);
                return;
            }
            if (stderr) {
                console.log(`stderr: ${stderr}`);
                return;
            }
            console.log(`stdout: ${stdout}`);
        });

# ...
  • Please make sure that your application is at least behind a password protection. Exposing docker.sock in any way is a security thing.
  • Here you can find other Docker client versions: https://download.docker.com/linux/static/stable/x86_64/
  • Please replace <PART_OF_YOUR_CONTAINER_NAME> with a part of your container name.