Cannot Create Directory "net_cls" Read Only Filesystem When Installing on Debian

Hi all,

I’ve been trying to to figure this problem out for a while, but I’m stumped. I’m trying to install Docker inside a container so that I can build Docker images in my containerized Jenkins install (not run them, just build them). The Dockerfile is based off Debian 8/Jessie. The relevant portion of the Dockerfile is:

RUN apt-get purge "lxc-docker*" && apt-get purge "*" && \ 
apt-get update && apt-get install -y -f --no-install-recommends sudo apt-transport-https ca-certificates && \
adduser root sudo && \
apt-get update && \
apt-key adv --keyserver hkp:// --recv-keys 58118E89F3A912897C070ADBF76221572C52609D && \
sudo apt-get install -y -f --no-install-recommends --force-yes docker-engine && \
sudo service docker start && \
sudo groupadd docker && \
sudo gpasswd -a jenkins docker && \
sudo service docker restart

Which should pretty closely match the instructions on I did have to change the source referenced in docker.list to use http and and --force-yes or it fails with an unknown method error.

When it gets to that point in the Dockerfile (basically the end), it fails with the following output:

Selecting previously unselected package docker-engine.
Preparing to unpack …/docker-engine_1.12.2-0~jessie_amd64.deb …
Unpacking docker-engine (1.12.2-0~jessie) …
Processing triggers for systemd (215-17+deb8u5) …
Setting up libnfnetlink0:amd64 (1.0.1-3) …
Setting up libxtables10 (1.4.21-2+b1) …
Setting up iptables (1.4.21-2+b1) …
Setting up docker-engine (1.12.2-0~jessie) …
invoke-rc.d: policy-rc.d denied execution of start.
Processing triggers for libc-bin (2.19-18+deb8u6) …
Processing triggers for systemd (215-17+deb8u5) …
mkdir: cannot create directory ‘net_cls’: Read-only file system
ERROR: Service ‘jenkins’ failed to build…

Further up in the output I’m also receiving some GPG errors (can’t validate signature, NO_PUBKEY), but the build is continuing.

My host machine is on AWS running Amazon Linux, with Docker 1.11.2.

Any input would be appreciated.

– Andrew

This is one of the challenging things when running Docker; Google for “Docker in Docker”. The recommended path is generally to bind-mount the host’s Docker socket into the CI environment, which technically gives the CI system root privileges on the host, but is straightforward and avoids a giant swath of ugly issues.

If that doesn’t work, you can docker run --privileged docker:dind. Docker has details on this image.

(My CI environment just reuses the host’s socket.)

RUN apt-get purge "lxc-docker*" && apt-get purge "*" && \
... && \
sudo service docker restart

As a general rule, never use a “service” or “initctl” or “systemctl” command in a Dockerfile. Containers tend not to run real init systems, so you get errors like

which I’m pretty sure is a “systemd wants to manage much more than is manageable in a container” error.

Ah thank you, the bind mounting seems to be the much better way to go. I updated my Dockerfile to


RUN curl -fsSLO$DOCKER_VERSION.tgz && \
tar --strip-components=1 -xvzf docker-$DOCKER_VERSION.tgz -C /usr/bin && \
groupadd -g 497 docker && \
gpasswd -a jenkins docker

To just download the client, and then add my jenkins user to the group (GID 497 is the GID of the docker group on the host so the container user has privileges). Then I set /var/run/docker.sock:/var/run/docker.sock as a volume in my docker-compose file. Thanks for the advice!