skip to Main Content

In scholar project, we use DevContainers to share same dev environment (for Symfony api):

{
  "name": "M2 Symfony CI/CD",
  "build": {
    "dockerfile": "Dockerfile",
  },
  "containerUser": "app",
  "remoteUser": "app",
  "mounts": [
    "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=cached"
  ],
  "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
  "workspaceFolder": "/workspace",
  "remoteEnv": {
    "HOST_PROJECT_PATH": "${localWorkspaceFolder}"
  }
}

with the following Dockerfile:

FROM php:8.3-fpm

RUN useradd -ms /bin/sh -u 1000 app

RUN groupadd -g 4200 docker
RUN usermod -aG docker app
RUN newgrp docker

RUN apt-get update && 
    apt-get install -y --no-install-recommends curl 
    procps 
    git 
    ca-certificates

RUN curl -sSLf 
        -o /usr/local/bin/install-php-extensions 
        https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions && 
    chmod +x /usr/local/bin/install-php-extensions && 
    install-php-extensions @composer

RUN install -m 0755 -d /etc/apt/keyrings && 
    curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && 
    chmod a+r /etc/apt/keyrings/docker.asc && 
    echo 
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian 
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | 
      tee /etc/apt/sources.list.d/docker.list > /dev/null && 
    apt-get update && 
    apt-get install -y docker-ce-cli docker-buildx-plugin docker-compose-plugin

RUN mkdir -p /var/run && 
    touch /var/run/docker.sock && 
    chown -R app:app /var/run/docker.sock

USER app

We mount the host docker sock to devontainer docker.sock so we can access our app from my web browser.

But the devcontainer docker.sock permission kept the host permissions (in my case root docker) so I had to create a new group within the Dockerfile with the same id (4200) and add the app user to the group but my friend docker group on his device is not the same so he is unable to run docker inside his dev container and cannot start the app.

We wonder if there is any way to get the docker group id from the host device to use it in the Dockerfile ?

Something like :

RUN groupadd -g ${HOST_DEVICE_GROUP_ID} docker

I’ve seen several post on SO which were all suggested to do it with args and docker run command but it is not fitting in our case as we don’t run this command.

2

Answers


  1. Chosen as BEST ANSWER

    We finally found a workable solution which doesn't require to know host docker user group id.

    In the DevContainer Dockerfile, just keep the app user:

    RUN useradd -ms /bin/sh -u 1000 app
    
    # These lines are no longer needed
    #RUN groupadd -g 4200 docker
    #RUN usermod -aG docker app
    #RUN newgrp docker 
    

    Then we modified the devcontainer.json file :

    {
      "name": "M2 Symfony CI/CD",
      "dockerFile": "./Dockerfile",
      "mounts": [
        "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=cached"
      ], // Bind host docker sock to devcontainer docker sock
      "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
      "workspaceFolder": "/workspace",
      "remoteEnv": {
        "HOST_PROJECT_PATH": "${localWorkspaceFolder}"
      },
      "containerUser": "root",
      "postCreateCommand": "chown app:app /var/run/docker.sock",
      "remoteUser": "app"
    }
    

    "containerUser" : Build with 'root' user
    "postCreateCommand" : Once builded, give ownership of docker.sock to 'app' user (created in Dockerfile)
    "remoteUser" : Connect to DevContainer with 'app' user

    This allow to use Docker inside the DevContainer and keeps the app volumes on host device to not lose any work.


  2. You cannot know the eventual host group ID in the Dockerfile. Imagine you docker build the image, docker push it to a repository, and then docker run it from another machine; the host’s Docker socket could be owned by a different group ID on the new machine, and potentially every machine you run the image on will have a different group ID.

    When you run the container, you’ll have to inject the correct group ID. For example,

    sudo docker run 
      --group-add $(getent group docker | cut -d: -f3) 
      -v /var/run/docker.sock:/var/run/docker.sock 
      ...
    

    As always, remember that anyone with access to the Docker socket can all but trivially root the host system, and the Docker socket won’t be accessible in other container environments like Kubernetes. Use extreme caution if you do have access to this. Consider rearchitecting your application to not need it at all.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search