We've begun to use containers when creating tools and utilities so individual developers don't have to bother installing prerequisites. Works great, as in:
docker run --rm -v $PWD/input.yaml:/input.yaml our.registry.com/dev/toolA /input.yaml
Until toolA
needs to call another utility, toolB
, that is also wrapped in a container.
Is there a generic way to run a container from within a container, so that it works with docker, podman, or whatever the container-tech-du-jour is without toolA
's caller having to add "scary" extra parameters like e.g. --privileged=true
or -v /var/run/docker.sock:/var/run/docker.sock
?
I'm aware that one can run docker-in-docker, and apparently one can also run podman-in-podman, but that is not recommended. Adding -v /var/run/docker.sock:/var/run/docker.sock
is the recommended approach, but that is docker-only, right?
Because otherwise this is a leaky abstraction. Currently I build toolA
by including the essential bits of the toolB
container in toolA
, making toolA
sensitive to changes in the implementation of toolB
, which I'd like to avoid. Or I could build toolA
but only support docker and require users to add the -v /var/run/docker.sock:/var/run/docker.sock
parameter :-(.
Is there a more elegant way to call toolB
s container from inside toolA
's container that works with all common container techs and doesn't require extra parameters when starting toolA
?
Is there a generic way to run a container from within a container [...] without having to add "scary" extra parameters like [...] -v /var/run/docker.sock:/var/run/docker.sock?
No.
(You do have to mount the host's Docker socket; the calling container does not need to be --privileged
; you cannot limit what the calling container can do once it has access to the socket, so it can itself launch privileged containers, or launch a container bind-mounting the host's /etc
directory, or otherwise do naughty things. I'm not actually sure how this interacts with Podman.)
Especially if the container needs to write back to the host system, it's hard to make the docker run
command be usably compact. You'll need a -u
option to specify the host user ID, -v
options for the Docker socket and the current directory, --rm
, and the repository name, all as overhead, every time you run the command. I might prefer using a native command, maybe in a widely-available scripting language like Python or the Bourne shell.
If you still want to run this from a container, you could COPY
or otherwise install tool B into the same container, so you can make a normal subprocess invocation to launch it; or break tool B into a library and an application, and include the library in tool A (kind of what you're doing now but more formalized).