File permission problems with volume containers starting containers as non-root user (www-data)

For security reasons I try to run docker containers as non-root. In my case I would like to start a container as www-data. ResinOS host contains a www-data user/group with id 33 (as Debian does). As described in How to use volumes with rdt pushing a container to the device maps the host /mnt/data/resin-data/<app-name>/ into /data on the container.

Since /mnt/data/resin-data/<app-name>/ is creates as root, running the container fails with a file permission problem since www-data can’t write to /data. I found a workaround by stopping the container, changing ownership of /mnt/data/resin-data/<app-name>/ to www-data:ww-data. Successive starts worked fine as long i did not delete the directory.

Is there an alternative way to set directory permissions for /mnt/data/resin-data/<app-name>/? I thought --before could be use, but the --before command is run locally on the machine where resin-cl is executed (and not on the device host).

Another problem running a container as non-root is mapping the UID/GID from container to the host system. My image worked only with the resin-Debian base image since www-data UID/GID matches on host and image. I was not able to create a working image from Alpine base image where the UID/GID is 82 (and not 31).

Do you know a way to map UID/GUID 82 (from the container) to the UID/GID on the host (32)?

kind regards
Max

I’m asking around on our internal chat for some help with this one. It’s a Bank Holiday weekend, so we’re down to a much reduced team, so it might be a few days before someone more expert than I steps in.

hey @maxh, I think you will find this post useful https://denibertovic.com/posts/handling-permissions-with-docker-volumes/. Looks like it might work.

Hey @maxh, what kind of security reasoning are you thinking about?
Are you deploying to the device locally (with rdt push / resin local push) or over-the-Internet deploy?

If you are doing local deployment, being a non-root user within the container is probably not a big save, as the whole device is open on the local network already.

Still, your point of /data in the container should be writable for all users would be a reasonable thing (filed an internal issue about that)! :white_check_mark:

If you want to map the users, the best I’d think would be to manually recreating the users in question in your Dockerfile (removing and readding the user, probably), where you can set the UID yourself (unless it’s already been used). Having world-writable /data, or using root unless you have very specific requirements.

I currently evaluate ResinOS as base OS for my “private-cloud-mini-server”. I try learning container technology by containerizing all services currently running on my Raspi with Raspian.

The test device with ResinOS (Odroid C1) runs on my home LAN (no internet). And yes, since I use the development image with resin local push it is insecure. Nevertheless I try to create my containers in a way to make them secure for my future real “private-cloud-miniserver”.

BTW, ResinOS is really amazing. After I cleared the first hurlde (installing resin-cli - not that easy if you never worked with npm), i was surprised how easy it was to get my first container running.

All i have to figure out is how i get a secure (non-developer) image and how to put my containers on it.

Just to let you know, we are considering providing a version in future with Node bundled, to solve this entirely: Release standalone version (that ships with Node.js) · Issue #484 · balena-io/balena-cli · GitHub. Feel free to follow that ticket if you want updates.