-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
updateUID.Dockerfile build step should occur before any features are installed (specifically docker-from-docker) #6461
updateUID.Dockerfile build step should occur before any features are installed (specifically docker-from-docker) #6461
Comments
We do the UID update last because that depends on the local machine whereas everything else could be prebuilt in CI. @Chuxel @joshspicer Can we change the sockets ownership to root:docker and make the regular user part of the docker group? That should keep working after the user's UID and default GID changed. |
Yeah the code in this section attempts to deal with this situation: https://github.com/microsoft/vscode-dev-containers/blob/5623b4a28cdd5cf9bae1b3318d52862657d46b89/script-library/docker-debian.sh#L279 There is an entrypoint script and since the Docker CLI is present but not the engine, so a docker-host group is created with same GID and the user is added to it unless that GID is "0"... in which case socat is used as a final fallback. I am wondering if the entrypoint script hasn't been fired in the situation you're talking about here. Can you post your entire devcontainer.json and Dockerfile? Also, note that right now if you are using features, you need to reference the feature even if it has been pre-built. This brings across configuration needed at runtime. That said, we're talking about improving this (e.g. devcontainers/spec#18) |
devcontainer.json // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/python-3
{
"name": "Python 3",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"VARIANT": "3.8",
// Options
"NODE_VERSION": "none"
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"python.languageServer": "Pylance",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"python.linting.flake8Enabled": true,
"python.linting.banditEnabled": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
},
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"psioniq.psi-header",
"ms-azuretools.vscode-docker",
"njpwerner.autodocstring",
"mongodb.mongodb-vscode",
"eamodio.gitlens"
],
"containerEnv": {
"PYTHONPATH": "${containerWorkspaceFolder}",
},
"postCreateCommand": "/scripts/setup_env.sh",
"remoteUser": "vscode",
"features": {
"docker-from-docker": "latest",
"git": "os-provided",
"git-lfs": "latest"
}
} Dockerfile # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/python-3/.devcontainer/base.Dockerfile
# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
ARG VARIANT="3.10-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
RUN apt-get install wget apt-transport-https gnupg lsb-release && \
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add - && \
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list && \
apt-get update && \
apt-get install trivy
COPY .devcontainer/scripts /scripts I have also attempted manually setting the entrypoint or even executing the docker-init.sh script from within my pipeline but I didn't seem to notice any difference. As for you last point I'm not sure what you mean by "you need to reference the feature even if it has been pre-built". Do I need to be manually specifying additional |
Trying to understand your scenario a bit better - are you using Jenkins to launch the dev container instead of Remote - Containers (or Codespaces if you're using that)? I'm not familiar enough with Jenkins to know exactly what it does when spinning up a container from an image, but I can make some educated guesses. The image alone is not enough to make everything work as expected currently. We are working on the ability to use a CLI to launch with all the needed config (devcontainers/spec#9). However, today you'd need to manually set the entrypoint if you are using this directly. e.g., from the command line: docker run -v /var/run/docker.sock:/var/run/docker-host.sock:ro --entrypoint /usr/local/share/docker-init.sh So, I suspect |
Yes, I am using Jenkins to run the pipeline stages inside of the container. Using the I have extracted this from the Jenkins build logs. This is the command that gets generated to run the container I've had to redact some things but I think this should get the idea across. docker run -t -d -u 1005:1006 -v /var/run/docker.sock:/var/run/docker-host.sock:ro --add-host=host.docker.internal:host-gateway -w /home/jenkins/workspace/my-project_master -v /home/jenkins/workspace/my-project_master:/home/jenkins/workspace/my-project_master:rw,z -v /home/jenkins/workspace/my-project_master_tmp:/home/jenkins/workspace/my-project_master_tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** image-built-by-devcontainer cat Where all the I'll give adding in the entrypoint another go but I seem to remember that not working. |
So just added back in the argument to manually specify the docker-init.sh entrypoint. Still getting the same output as my first post. Updated Command
If the docker-init.sh is supposed to be creating a docker group with the matching GID and adding the user to that group it doesn't look like it is actually working because the group list still just shows vscode. |
Can you start as root and |
Okay, there's actually a few things potentially going on here.
However, @chrmarti Does the dev container CLI's build step do GID/UID syncing? I would expect that to be done at the time it's spun up... that's one of the reasons we want the exec step for the dev container CLI. I would expect...
... to result in an image with vscode's UID being 1000. When I just tried, that seemed to be what happened. When I then run the command above that specifies
The 1005 user isn't in the sudoers file, so nothing would update anyway.. |
Correct, |
Ok - I think I have a fix for the other issue queued up. |
Okay I think this is a key detail I was missing, but makes sense now in retrospect. With this in mind I made the following changes and things seem to be working.
Are you sure about that? I see the following in my build about when the devcontainer CLI is building the image
Unless I am misunderstanding what you mean here? |
I fixed the upstream script to handle this situation. On the uid - that's coming from the CLI? Odd - @chrmarti was there an earilier version of the CLI that did this? |
Possibly, that would have been a bug. The latest doesn't run the UID update during |
Getting back around to looking at this. I've updated the devcontainer cli and no longer see the GID update during build so must have worked that way in a previous version.
@Chuxel I think I'm understanding now. But even after this fix I'm not sure all the issues are resolved. If I understand correctly you would then make sure to start the container with Also it seems that even after this fix you still have to re-connect to the container as Docker Run
Inside Container vscode ➜ /workspaces/project $ id
uid=1000(vscode) gid=1000(vscode) groups=1000(vscode),102,998(nvm),999(pipx)
vscode ➜ /workspaces/project $ sudo su vscode -c "id"
uid=1000(vscode) gid=1000(vscode) groups=1000(vscode),985(docker),998(nvm),999(pipx)
vscode ➜ /workspaces/project $ cat /etc/group | grep -i docker
docker:x:985:vscode
vscode ➜ /workspaces/project $ touch test.txt
touch: cannot touch 'test.txt': Permission denied Alternatively starting the container disconnected and reconnecting with Docker Run
Docker Exec docker exec -it -u vscode devcontainer bash Inside Container vscode ➜ /workspaces/project $ id
uid=1000(vscode) gid=1000(vscode) groups=1000(vscode),985(docker),998(nvm),999(pipx)
vscode ➜ /workspaces/project $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d924a2e01bbc test "/usr/local/share/do…" 2 minutes ago Up 2 minutes devcontainer
vscode ➜ /workspaces/project $ ls
ls: cannot open directory '.': Permission denied |
Correct. The fix would solve the problem of the docker group getting updated, but the files in the bind mount into the container is still the host's user while the container itself has the non-root user as 1000:1000. The UID/GID shift happens at the time the container is started, not when the image is built since each system can be different. The upcoming dev container CLI should do this automatically by allowing you to execute commands inside of it. But in this situation you'd need to apply the usermod/groupmod manually via a Dockerfile. That said, you can opt to run inside the container as root which avoids that problem entirely, but I realize that has security implications to the host. That said, if you're already running docker as root and there's sudo in this image, it wouldn't be a new risk. |
Just to write down what that dockerfile would look like: FROM <your image name here>
ARG UID=1000
ARG GID=1000
ARG USERNAME=vscode
USER root
RUN usermod -u ${UID} ${USERNAME} && usermod -g ${GID} ${USERNAME}
USER vscode Building the image would then be:
|
And this would be an additional image build after the I.e.
Where updateUID.dockerfile is the one you showed above? Definitely looking forward to the update to the devcontainer CLI however. I see there currently exists a |
@mdgilene Yep - that's correct. @chrmarti is working on the CLI as a part of devcontainers/spec#9 this iteration. |
Steps to Reproduce:
I am using the docker-from-docker container feature perfectly fine from my local windows based Docker environment. I am then attempting to utilize the dev-container-cli to build and run my builds within my CI/CD environment (in this case Jenkins).
Build devcontainer with dev-container-cli
This correctly builds the image and runs the
updateUID.Dockerfile
build step to adjust thevscode
user's UID/GID to match that of the jenkins user launching the container.Launch Jenkins agent making sure to mount the docker socket
Attempt any docker command from inside the container to receive a "Permission denied" error.
Inspect current UID/GID and
/run
directory to see that/var/run/docker.sock
is still owned by user 1000 instead of the updated UID (in this case 1005)From what I can tell the docker installation step occurs before the UID/GID update thus installing and configuring docker only for UID 1000
The only solution I have found so far is to update the owner of
/var/run/docker.sock
on the host machine to the Jenkins user rather than root. Which....is less than ideal.The text was updated successfully, but these errors were encountered: