Files created within a Docker container mapped to a WSL2 directory are created by a different user and so are not modifyable.
What is the strategy for handling this?
Open VSCode on the WSL folder ~/workspaces/dotnet1
In the terminal enter docker run -it -w /app -v ~/workspaces/dotnet1:/app --rm mcr.microsoft.com/dotnet/sdk:3.1 dotnet new console
Open Program.cs in VSCode, edit it and save
Result: Error: EACCES: permission denied
docker versionDocker version 19.03.13, build 4484c46d9d
docker infoClient:
Debug Mode: false
Plugins:
scan: Docker Scan (Docker Inc., v0.3.4)
Server:
Containers: 5
Running: 0
Paused: 0
Stopped: 5
Images: 37
Server Version: 19.03.13
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 8fba4e9a7d01810a393d5d25a3621dc101981175
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.19.128-microsoft-standard
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 12.37GiB
Name: docker-desktop
ID: JUUL:CH7W:DIJD:5VTG:VOOD:LGBA:RHQU:ZTSO:RBNI:Y55H:HH35:KB3P
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
I can see that in the container the default user has id 0 using id -u and that in my WSL distro my user is id 1000.
You can set the id of the user the container runs using using docker run --user=1000 ... and that works even if the specified user does not exist within the container. But that doesnt help in this case because dotnet new will then fail with "access denied to /.dotnet"
It appears that the dotnet image only works when run using the root user. But if that means that every time I use it to make a change in my project I'm going to have to chown my entire project directory in WSL2 just to be able to do anything that is going to really suck.
This is not specific to the .NET container. You can get this same behavior with any base OS container. If you look at the permissions of your workspaces folder, you'll see:
drwxr-xr-x 3 root root 4096 Dec 9 14:25 workspaces
Notice that the owner is root since that is what the container runs as. This is a general problem when working with Docker volume mounts.
You can get this same behavior without involving .NET by running a base OS container. For example:
docker run -it -w /app -v ~:/app --rm alpine touch file1.txt
That will create a file1.txt file in your home directory that you'll also not be able to write changes in VS Code.
This post goes into detail on the general problem: https://denibertovic.com/posts/handling-permissions-with-docker-volumes/.
If you need further assistance, I would suggest posting to Stack Overflow where there is a wide range of experts that can help out.
Since this is not specific to .NET, I'm closing this issue.
But that doesnt help in this case because dotnet new will then fail with "access denied to /.dotnet"
It appears that the dotnet image only works when run using the root user.
The .NET images will work with non-root users. You must add the user, you cannot just specify an arbitrary user via docker run.
FROM mcr.microsoft.com/dotnet/sdk:5.0
RUN useradd -ms /bin/bash -u 1000 testuser
> docker build -t test .
> docker run --rm --user=testuser test dotnet new
That worked beautifully. Thanks for the explanation.