Search code examples
linuxbashdockervscode-remote

Run VScode in Container with user created by the entrypoint


I have a container that creates a user on start, with the correct UID/GID (this docker is available for a developer team, which may not share the same ids). In order to let them compile/access source files it necessary to have a user in the container that has the same id as the host user.

The entrypoint part that creates the user looks like this :

if ! id -u "${USER_ID}"; then
    adduser \
        --disabled-password \
        --gecos "Docker Builder" \
        --gid "${USER_GID}" \
        --uid "${USER_ID}" \
        --shell /bin/bash \
        --home "${USER_HOME}" \
        "${USER_NAME}"
fi

Where the variables are given by the docker exec -e

Up to now I was only attaching VScode to running container, and specifying the remoteUser for this container ID is sufficient. But with this way of attaching to a container, I can't open multiple VScode windows on one container. To achieve this, I must use devcontainer.json.

I looked in the documentation but I can't find a way to tell devcontainer.json to connect to a user that is not yet defined in the container.
Or in another way to say this, can I change the user in runtime ?

This is what I have done so far.

  • tasks.json
"inputs": [
  {
      "id": "get_uid",
      "type": "command",
      "command": "shellCommand.execute",
      "args": {
          "command": "id -u",
          "useFirstResult": true
      }
  },
  {
      "id": "get_gid",
      "type": "command",
      "command": "shellCommand.execute",
      "args": {
          "command": "id -g",
          "useFirstResult": true
      }
  }
]
  • devcontainer.json
"image": "myDocker",
"forwardPorts": [3000],
// Emulate : docker exec -e
"containerEnv": {
  "LOCAL_USER_NAME" : "vscode",
  "LOCAL_USER_HOME" : "/home/vscode",
  "LOCAL_USER_ID" : "${input:get_uid}",
  "LOCAL_USER_GID" : "${input:get_gid}"
},
"overrideCommand": false

I would like not to change/override the Dockerfile, because it would break the mechanism of creating a single container independently from the UID/GID.
May be I missed something, or I am looking in the wrong direction ?


Solution

  • I finally got it to work, thanks to @DavidMaze who pointed me in the right direction.

    I changed my entrypoint and my Dockerfile.
    Now, I create a generic user in the Dockerfile and change it's uid/gid in the entrypoint if necessary.

    This permit me to use runArgs from devcontainer.json, and let VScode deal with it's own entrypoint. My devcontainer.json now looks like:

      "image": "myDocker",
      "forwardPorts": [3000],
      "runArgs": [
        "--user=user"
      ]
    

    I don't use the tasks.json anymore here, but I now know how to do some dynamic replacements.

    Thanks