dotnet / sdk-container-builds

Libraries and build tooling to create container images from .NET projects using MSBuild
https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
MIT License
175 stars 30 forks source link

How should one setup container volumes with approach? #526

Open baywet opened 7 months ago

baywet commented 7 months ago

I'm looking for the equivalent of

VOLUME /app/output

in the csproj

If this is already supported today, it should be documented here

baronfel commented 7 months ago

Volumes are not currently supported. This is actually the first request we've had for them. Would you mind describing what you'd do with them, and how you'd use them on the container versus a compose file or something?

baywet commented 7 months ago

Well, as a public container producer (mcr.microsoft.com/openapi/kiota) I added the volumes to the dockerfile so they are "advertised" to consumers when the inspect the image. This way they "know": "oh this container will look at those volumes if I map them" I'd be expecting to be able to do the same with this approach of building my container image.

baronfel commented 7 months ago

In https://github.com/dotnet/sdk-container-builds/discussions/521 I discovered a new use case for Volume support that bumps the priority up a bit for me - Volumes are how you get proper permissions configured for any volume mounts that users may do.

This is especially important for rootless execution - a user can mount a volume via the Docker CLI but those mounts won't have the same ownership as the users home directory, so the rootless app won't be able to access them. To correct this the app would need to declare Volumes for the expected mount locations, which effectively works like creating a directory with the property ownership at that location.

baronfel commented 7 months ago

I did some investigation and this may not be as simple as I had hoped. Some reference materials:

When you create a volume in a Dockerfile, a new entry is added to the Volumes property of the configuration:

"Volumes": {
    "/home/app/data": {}
},

The Docker daemon still mounts this as root:root, however - regardless of what configuration the image author or the container runner may pass. Podman has some controls to help support this (see the linked article) but there is not currently any standard here. I worry that complex rootless execution modes will be difficult for .NET users using the SDK container tooling to adopt as a result.

# blah is a container based off of the dotnet/aspnet image and set to use the app user + a volume at /home/app/data 
docker run -it --rm --entrypoint /bin/sh blah
/ $ whoami
app
/ $ ls -la ~
total 20
drwxr-sr-x    1 app      app           4096 Nov 29 22:39 .
drwxr-xr-x    1 root     root          4096 Nov 14 14:57 ..
-rw-------    1 app      app             16 Nov 29 22:39 .ash_history
drwxr-xr-x    2 root     root          4096 Nov 29 22:39 data
/ $ ls -la ~/data/
total 8
drwxr-xr-x    2 root     root          4096 Nov 29 22:39 .
drwxr-sr-x    1 app      app           4096 Nov 29 22:39 ..
mu88 commented 7 months ago

Just for my understanding: is rootless such a new and uncommon scenario? It surprises me that there's no established solution for such scenarios yet

zakeryooo commented 4 months ago

Is there any proper workaround for this yet? I was using dotnet publish then mounting the resultant image with a volume via the docker command line but now with the rootless images I can't write to the volume.

I can't find it in the docs but is there an option to at least revert back to a root image as before? What I'm running isn't important security-wise... I just need it to work as before

Edit: Didn't realise you could just set <ContainerUser>root</ContainerUser> to get the old behaviour back. Thought you'd have to tell it it's a user with root permissions rather than just a user called root. Not perfect to have to run as root again but still better than it not working at all!