Start container from within container?

Hi all,

I have a question about a project I’m working on. I’m building a webapp which will allow me to launch various predefined tasks that help me to do my job more efficiently. These can be shellcommands, webrequests, litterly anything so I figured I could containerise alot of those tasks. Now, for some tasks it will be advantageous to split the workload in loads of small packages and hand those out to a lot of worker instances. So: Webapp to launch jobs, which starts worker containers to execute the actual work.
Only one problem: apparently I can’t talk to the docker daemon on the master from within a container. But if my app itself is containerised, then how do I allow it start new containers? Is there a way to overcome this? I guess there should be since Portainer (docker manager ui) is a comparable use case.

Thanks for any help and advice :slight_smile:

So, what I learned so far:
Portainer solves it by binding to the docker socket on the host (-v /var/run/docker.sock:/var/run/docker/sock).

So, to simulate what I’m going to try to achieve I’ve setup a jenkins container with docker plugins installed and i bound to the socket on the host (-v /var/run/docker.sock:/var/run/docker/sock).
Now, when I test the connection from jenkins to unix:///var/run/docker.sock I get a permission denied:

connect(..) failed: Permission denied: /var/run/docker.sock
java.net.ConnectException: connect(..) failed: Permission denied
Caused: io.netty.channel.AbstractChannel$AnnotatedConnectException: 
connect(..) failed: Permission denied: /var/run/docker.sock
	at io.netty.channel.unix.Errors.throwConnectException(Errors.java:107)
	at io.netty.channel.unix.Socket.connect(Socket.java:243)

Any ideas?

Cheers,
Cedric

And one google later, seems someone already did my exact use case with Jenkins:
getintodevops.com - The simple way to run Docker-in-Docker for CI

So to close this thread, if anyone ever has this same question. What I did to get it finally working after having added the bind to the socket on the host; run the following as root on the container:

update: Before you do this, read my last comment, it’s not necessary to do this installation to get this working I think.

apt-get update && \
apt-get -y install apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add 
/tmp/dkey && \
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable" && \
apt-get update && \
apt-get -y install docker-ce

After this, which basically installs all docker components within the jenkins docker container you can verify that you are actually binding to the host docker by checking currently running containers:

docker ps

Actually, after having ran docker ps, I checked jenkins again and I still had the permission denied error. Solution was to make jenkins the owner of the bind to the docker host socket, and actually now I think this was the only necessary requirement to let jenkins connect to it, the installation of all the docker components is redundant.

chown jenkins /var/run/docker.sock

When you bind the hosts docker.sock into the container, you only need to install docker-ce-cli, as you command the hosts docker.sock to execute operations.
You need to find out the GID of the docker group on the host and apply this GID to your user inside the container, if the user is anyone else than root.

Are you realy sure this is what you want? https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/

Hey Metin,
Well, yeah I did find it a bit odd. I’d expect I could just talk to the API but then when I tried that I learned that containers don’t have any route to the host over network, it gets blocked. Well, you could fix that in various ways but they are all equally ugly, so binding to the docker socket seems to be the most elegant solution. Or am I missing something that I really should look into?

If you want to interact with the docker api, there is no away arround either directly interacting with the docker.sock or with rest calls (after publishing the api to a tcp socket).

Ok, and yeah I understand there are security implications, that’s why this is an isolated system dedicated to docker development :slight_smile:

Thnx for the hints

You might want to take a look at https://docs.docker.com/develop/sdk/. You will find examples and libraries for the programming language of your choice - even if it’s just bash leveraging curl :slight_smile: