I am using vscode devcontainers.
My enviroment, setup, and execution is as follows:
[email protected]
,Docker version 23.0.4, build f480fb1
,Docker Compose version v2.17.2
,ubuntu 20
.devcontainer
|- .devcontainer.json
|- Dockerfile
.devcontainer.json:
{
"name": "Node.js",
"build": {
"dockerfile": "Dockerfile",
},
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"terminal.integrated.profiles.linux": {
"bash": {
"path": "/bin/bash",
"icon": "terminal-bash",
},
},
},
"extensions": [
"dbaeumer.vscode-eslint"
],
}
Dockerfile:
FROM mcr.microsoft.com/devcontainers/typescript-node:20
$ devcontainer build .
[12 ms] @devcontainers/cli 0.35.0. Node.js v16.14.2. linux 5.15.0-41-generic x64.
[519 ms] Start: Run: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/devcontainercli-craig/container-features/0.35.0-1682146167065/Dockerfile-with-features -t vsc-testdevc-badaeb5eab5ce3c45f2eb0d49d69644c94fb162ab4a701e8569eeb7219cdbf07 --target dev_containers_target_stage --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label /home/craig/testDevc/.devcontainer
[+] Building 0.1s (6/6) FINISHED
=> [internal] load build definition from Dockerfile-with-features 0.0s
=> => transferring dockerfile: 1.38kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for mcr.microsoft.com/devcontainers/typescri 0.1s
=> CACHED [dev_container_auto_added_stage_label 1/1] FROM mcr.microsoft. 0.0s
=> preparing layers for inline cache 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:0fa55cc0ebea427319bfb7cb68823433bc84e04ebb016 0.0s
=> => naming to docker.io/library/vsc-testdevc-badaeb5eab5ce3c45f2eb0d49 0.0s
{"outcome":"success","imageName":["vsc-testdevc-badaeb5eab5ce3c45f2eb0d49d69644c94fb162ab4a701e8569eeb7219cdbf07"]}
$ devcontainer open
[229 ms] @devcontainers/cli 0.35.0. Node.js v16.14.2. linux 5.15.0-41-generic x64.
From the vscode terminal inside the container
node ➜ /workspaces/testDevc $ ls -al
total 12
drwxrwxr-x 3 root root 4096 Apr 22 06:49 .
drwxr-xr-x 3 root root 4096 Apr 22 06:49 ..
drwxrwxr-x 2 root root 4096 Apr 22 06:49 .devcontainer
node ➜ /workspaces/testDevc $ ls -an
total 16
drwxrwxr-x 3 0 0 4096 Apr 22 07:11 .
drwxr-xr-x 3 0 0 4096 Apr 22 06:49 ..
drwxrwxr-x 2 0 0 4096 Apr 22 06:49 .devcontainer
node ➜ /workspaces/testDevc $ whoami
node
node ➜ /workspaces/testDevc $ id
uid=1000(node) gid=1000(node) groups=1000(node),998(nvm),999(npm)
node ➜ /workspaces/testDevc $ groups
node nvm npm
node ➜ /workspaces/testDevc $ cat > test.txt
bash: test.txt: Permission denied
node ➜ /workspaces/testDevc $
From a terminal outside the container:
craig@desk:0:~/testDevc$ ls -al
total 16
drwxrwxr-x 3 craig craig 4096 Apr 22 00:11 .
drwxr-xr-x 55 craig craig 4096 Apr 21 23:48 ..
drwxrwxr-x 2 craig craig 4096 Apr 21 23:49 .devcontainer
craig@desk:0:~/testDevc$ whoami
craig
craig@desk:0:~/testDevc$ id
uid=1000(craig) gid=1000(craig) groups=1000(craig),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare),255(common),998(docker),1001(craig1001)
craig@desk:0:~/testDevc$ cat > test2.txt
hello
craig@desk:0:~/testDevc$ cat test2.txt
hello
As you can see, user craig
on the host and user node
on the container share the same uid. I though that was enough to ensure that node
would be able to write files.
What am I missing? Could it be because the host is ubuntu linux and not a WSL?
Summary
This explains how to enable both the devcontainer
-created container and the host to both be able to write files on the same mounted directory.
1 - In the container configuration, the Dockerfile is modified so the group write permission flags will be set on write.
2 - On the host side, first a new group is created which matches the container group, and the host user is added to that group.
3 - Then, the development directores and files permission flags are set.
Dockerfile
Add this line to .devcountainer/Dockerfile:
RUN su node -c "echo 'umask 0002' >> /home/node/.bashrc"
For example, this a working .devcountainer/Dockerfile:
ARG VARIANT=20-bullseye
FROM mcr.microsoft.com/devcontainers/javascript-node:0-${VARIANT}
RUN su node -c "echo 'umask 0002' >> /home/node/.bashrc"
Add group on host
In the case of ubuntu 20 host, the uid of files owned by the user on the container are observed to be 100999. This will likely vary by system.
On the host create a group with gid 100999, and add the host user to that group. It is necessary to log out and log back in again for it to take effect.
sudo addgroup --gid 100999 g100999
sudo usermod -a -G g100999 craig
Set host development directory permissions
sudo find . -type d -exec chmod g+rwxs {} +
sudo find . -type f -exec chmod g+rw {} +
Edit: added this to step 3:
sudo find . -type d -exec chmod g+t {} +
This removes the "sticky bit" which prevents file deletion from the host side. (This "stick bit" doesn't interfere with writing, only with deletion, and it applies to parent directory of hte file, not the file itself).