Search code examples
linuxdockerchroot

How to start a chrooted directory as a docker container?


Consider I have a directory, for example /demoenv. I would like to start a binary in it as a docker container.

Essentially, it would work like a chroot, but with the numerous extra features (and, with the numerous disadvantages) what a docker container provides.

In this case, it is absolutely not a problem if it can't take part in the very useful docker image/container committing mechanism (I have an alternate solution for that).

Can I somehow do it?

  • My first trouble is that in this case, I don't really have an image to start.
  • My second problem is that the -v volume mount option (parameter of docker run) forbids mounting the root partition with the following message:

docker: Error response from daemon: Invalid bind mount spec "/demoenv:/": Invalid specification: destination can't be '/' in '/demoenv:/'.


Solution

  • Finally I found a workaround.

    Unfortunately, simply mounting "/" (either with the VOLUME command in the Dockerfile, or with giving the -v to docker run) doesn't work - it can't mount the root directory as a volume.

    Furhtermore, VOLUME in the Dockerfile doesn't seem to work at all.

    The best (or, least worse) solution what can be done: mounting the sub-directories as different volumes. Around so:

    docker run -d -h demobox --name demobox \
        -v /demobox/bin:/bin \
        -v /demobox/boot:/boot \
        -v /demobox/etc:/etc \
        -v /demobox/home:/home \
        -v /demobox/lib:/lib \
        -v /demobox/opt:/opt\
        -v /demobox/root:/root\
        -v /demobox/sbin:/sbin\
        -v /demobox/srv:/srv\
        -v /demobox/usr:/usr\
        -v /demobox/var:/var \
        demobox
    

    Unfortunately, it also needs to have a fake image to run (it is "fake" because all of its relevant /* directories will be over-mounted by the docker daemon). You can use anything for that (I used the default image of the distribution).

    Additional info: as entrypoint, we can also give /sbin/init to the container. In my tries, systemd wasn't able to run in it, but upstart could (apt-get install upstart). Giving /sbin/init as ENTRYPOINT to the Dockerfile, then calling a telinit 3 after starting the container, we can essentially run a docker container as a virtual server.