vscode-dev-containers icon indicating copy to clipboard operation
vscode-dev-containers copied to clipboard

Multistage Dockerfile support for docker-from-docker feature

Open sajaysurya opened this issue 3 years ago • 0 comments

Currently the docker-from-docker feature doesn't support multistage Dockerfiles

Relates to: Remote - Containers

It works well with the following Dockerfile

FROM python:3.10.5 
RUN apt-get update -q \
    && apt-get install -q -y --no-install-recommends \
        sudo
# add non-root user with sudo access (sudo required by docker-from-docker feature)
RUN adduser vscode
RUN echo vscode ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/vscode \
    && chmod 0440 /etc/sudoers.d/$USERNAME
USER vscode

and the following .devcontainer.json file

        "dockerFile": "Dockerfile",
        "containerUser": "vscode",
	"features": {
		"docker-from-docker": {
			"version": "latest"
		}
	}

It actually works with a named stage in the Dockerfile like

FROM python:3.10.5 AS vscode_dev
RUN apt-get update -q \
    && apt-get install -q -y --no-install-recommends \
        sudo
# add non-root user with sudo access (sudo required by docker-from-docker feature)
RUN adduser vscode
RUN echo vscode ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/vscode \
    && chmod 0440 /etc/sudoers.d/$USERNAME
USER vscode

as long as the build target in not explicitly mentioned in the .devcontainer.json file

        "dockerFile": "Dockerfile",
	"build": { "target": "vscode_dev" }, <--- NOTE: works without this line!
        "containerUser": "vscode",
	"features": {
		"docker-from-docker": {
			"version": "latest"
		}
	}

sajaysurya avatar Jul 03 '22 17:07 sajaysurya

I believe this is a bug, not a feature-request.

I'm having the same problem, but this has not always been the case. In older versions of either VS Code or the VS Code Remote - Containers extensions the docker-from-docker feature has been working as expected, even with multi-stage builds.

I have/had multiple devcontainers which was built before the summer, where the docker.sock is still linked/mounted at /run/docker.sock, despite that build using multi-stage Docker builds. I tried rebuilding one of them and suddenly docker.sock is no longer there.

Minimum viable test example below. Remove the "build" row from devcontainer.json to get a functioning docker.sock link. In both cases though, no matter if we add a target or not, both files are created under /tmp which shows everything is running. There is just something about suddenly specifying the target stage which breaks the docker.sock linking.

devcontainer.json

{
    "name": "Test",
    "dockerFile": "Dockerfile",
    "features": { "docker-from-docker": "20.10" },
    "build": { "target": "development" } // Remove this to make the linking of docker.sock work again
}

Dockerfile

FROM debian:11-slim AS base
RUN touch /tmp/test1.txt
FROM base AS development
RUN touch /tmp/test2.txt

Caaaas avatar Aug 11 '22 15:08 Caaaas

I believe this is a bug, not a feature-request.

I'm having the same problem, but this has not always been the case. In older versions of either VS Code or the VS Code Remote - Containers extensions the docker-from-docker feature has been working as expected, even with multi-stage builds.

I have/had multiple devcontainers which was built before the summer, where the docker.sock is still linked/mounted at /run/docker.sock, despite that build using multi-stage Docker builds. I tried rebuilding one of them and suddenly docker.sock is no longer there.

Minimum viable test example below. Remove the "build" row from devcontainer.json to get a functioning docker.sock link. In both cases though, no matter if we add a target or not, both files are created under /tmp which shows everything is running. There is just something about suddenly specifying the target stage which breaks the docker.sock linking.

devcontainer.json

{
    "name": "Test",
    "dockerFile": "Dockerfile",
    "features": { "docker-from-docker": "20.10" },
    "build": { "target": "development" } // Remove this to make the linking of docker.sock work again
}

Dockerfile

FROM debian:11-slim AS base
RUN touch /tmp/test1.txt
FROM base AS development
RUN touch /tmp/test2.txt

A workaround to get docker-from-docker working again while keeping the multi-stage builds

In your Dockerfile, add the installation of the docker-ce-cli (NOT docker-ce, containerd.io etc, just the cli) Below is basic example for Debian, follow the Docker installation instructions for the relevant distro if you are running something else, but make sure you don't install anything but the cli, since we want to run on our host machines docker.

RUN apt update
RUN apt install -y ca-certificates curl gnupg lsb-release
RUN mkdir -p /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt update
RUN apt install -y docker-ce-cli

Add a postCreateCommand to devcontainer.json which links the /run/docker-host.sock to the /run/docker.sock. Remember to keep the docker-from-docker feature, since that adds our docker-host.sock bind mount, which we need.

"postCreateCommand": "ln -s /run/docker-host.sock /run/docker.sock"

Rebuild the container. Everything should be working again.

Caaaas avatar Aug 11 '22 15:08 Caaaas

This actually sounds like features may not be respecting the "target" property or there's some sort of odd conflict which I'd agree is a bug. @chrmarti @jkeech @joshspicer @alexdima - you agree? This could be another side effect of v2 features support. If so, we should probably raise this at https://github.com/devcontainers/cli

Chuxel avatar Aug 11 '22 17:08 Chuxel

Continuing in https://github.com/devcontainers/cli/issues/120. Thanks.

chrmarti avatar Aug 12 '22 09:08 chrmarti