2

I'm trying to start a docker container inside the docker build process.

I'm trying to build and pack one project inside a Docker container but its build process internally requires a running docker to actually build some unrelated image and there is no way excluding that step from the build process.

So far I got to the point where I was able to install docker inside docker build process, but I can't start the docker container (tried multiple base images).

Here is one of the ways I tried to use Docker during build process:

FROM maven:3.9.9-eclipse-temurin-11 as builder

RUN apt-get update --yes --quiet && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    apt-transport-https ca-certificates curl software-properties-common gnupg
RUN install -m 0755 -d /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
RUN chmod a+r /etc/apt/keyrings/docker.asc
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt update --yes --quiet
RUN apt-cache policy docker-ce
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

USER root
RUN usermod -aG docker root
# Fixing the bug: https://forums.docker.com/t/etc-init-d-docker-62-ulimit-error-setting-limit-invalid-argument-problem/139424
RUN sed -i 's/ulimit -Hn/ulimit -n/g' /etc/init.d/docker

RUN service docker start

RUN docker run hello-world

Last line throws the following error:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.

So, I tried to exclude that line, bash into the container and see what's going on. I see that service docker start actually starts a service for a second or so end then the process fails. Quick logs investigation show the following:

time="2024-10-12T15:21:02.998983540Z" level=info msg="containerd successfully booted in 0.042406s"
time="2024-10-12T15:21:04.001703179Z" level=error msg="failed to mount overlay: operation not permitted" storage-driver=overlay2
time="2024-10-12T15:21:04.001745444Z" level=error msg="exec: \"fuse-overlayfs\": executable file not found in $PATH" storage-driver=fuse-overlayfs
time="2024-10-12T15:21:04.001816599Z" level=warning msg="Unable to setup quota: operation not permitted\n"
time="2024-10-12T15:21:04.008983779Z" level=info msg="Loading containers: start."
time="2024-10-12T15:21:04.016718098Z" level=info msg="unable to detect if iptables supports xlock: 'iptables --wait -L -n': `iptables v1.8.10 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)`" error="exit status 4"
time="2024-10-12T15:21:04.026966817Z" level=info msg="stopping event stream following graceful shutdown" error="<nil>" module=libcontainerd namespace=moby
time="2024-10-12T15:21:04.027063083Z" level=info msg="stopping healthcheck following graceful shutdown" module=libcontainerd
time="2024-10-12T15:21:04.027108245Z" level=info msg="stopping event stream following graceful shutdown" error="context canceled" module=libcontainerd namespace=plugins.moby
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to register "bridge" driver: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.10 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)
 (exit status 4)

So, it seems that I have some network misconfiguration, but can't figure out what exactly.

4
  • Have you tried the official image? Also, why do you think you need this? It's generally not a good idea, and many time there are much easier ways to achieve what you want. Commented Oct 12, 2024 at 15:40
  • As an example, a multistage build can be a good starting point. Commented Oct 12, 2024 at 15:51
  • Thank you for insights! Yes, I tried official docker image, but it doesn't contain any docker installed and have the same problem. Also, about multi-stage build. I use them actually. I shared a portion of dockerfile without multi-stage for simplicity. I personally would also love to avoid this complexity, but as I said, I can't change the build process of the project I'm trying to build inside the docker and it by itself requires docker to be installed and running. Commented Oct 12, 2024 at 16:16
  • I think you should make that internal docker build process a part of this Dockerfile above. The system you are executing "RUN" command on is not a fully functional system, and I don't think that the docker service will run under it properly. Commented Oct 12, 2024 at 19:40

1 Answer 1

1

You can't do this the way you describe it.

For Java applications, a very old-school approach (before multi-stage builds existed) was to build the jar file on the host system. Since one of the major selling points of Java is that the compiled class files are platform-independent, you don't necessarily need a matching toolchain in the image. Your Dockerfile could be just

FROM eclipse-temurin:21-jre
COPY target/app-*.jar /app.jar
CMD ["java", "-jar", "/app.jar"]

and then you'd have a two-step build process on the host

sudo mvn package
sudo docker build .

If you can separate out the tool invocation from the rest of your build process, you could also potentially use a multi-stage build for this. Say you'd invoke the tool like

sudo docker run --rm -u "$(id -u)" -v "$PWD:/data" \
  some-image \
  some-tool -i /data/data.in -o /data/data.out

Then you could have a dedicated Docker build stage to run this

FROM some-image AS build-tool
WORKDIR /data
COPY data.in ./
RUN some-tool -i data.in -o data.out

FROM maven:3.9.9-eclipse-temurin-11 as builder
...
COPY --from=build-tool /data/data.out src/main/resources
...

You can't really run another image from within a Dockerfile without this multi-stage build setup, though. You especially can't run another Docker daemon. The Docker daemon is a little tricky to run from inside a container; the most common way to do it is to run the docker:dind image, but even that comes with the proviso that it must run as a privileged container. There's no option to run a privileged build or a privileged build step, though, so the nested Docker daemon won't work.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the explanation! I was hoping to avoid asking a user to install Java + Maven on the host machine as it's not user-friendly because it get's complicated choosing proper Java version and setting up environment. For now I decided to contribute the ability to disable Docker build during project build as it was easier then starting Docker inside a Docker build process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.