Hello all,
I have a web app that uploads a file and need the uploaded file to be persisted in a volume.
I have a Dockerfile with the following - following best practises π
RUN mkdir /uploaded-files && \
chown -R node:node /uploaded-files && \
USER node
In the image the ownership / access is correct

But when the container is running the directory is owned by 'root'.

But the container is running using the 'node' user.

The directory is mounted to a volume of the same name on the host machine. If I run an image without USER node so it's running as 'root' it all works fine.
Anyone know why the ownership of this directory is changing when the container runs?
edit----->
Even the /home/node directory is owned by root and not node π
Looks like there is a syntax error. There shouldn't be a && \ after the chown because USER is a docker directive.
Hi @LaurentGoderre
Apologise, I've typed that incorrectly.
I've tried doing the following.
RUN mkdir /uploaded-files && \
chown -R node:node /uploaded-files
USER node
RUN mkdir /uploaded-files && \
chown -R node:node /uploaded-files && \
chmod -R 777 /uploaded-files
USER node
I'm not sure if it's to do with the volume on the host being owned by root?
As when I run the container without it being bound to a volume the directory in the container has node being the owner.
The docker-compose.yml is like this
version: '3'
services:
app:
image: app:1.0.0
environment:
*variables in here*
ports:
- "3210:3000"
volumes:
- /uploaded-files:/uploaded-files
volumes:
uploaded-files:
If I stop the container, remove the volume and restart the container then it creates a volume called root_uploaded-files
If I stat the directory it is as follows
[root@ahv-docker1-dev /]# stat uploaded-files/
File: βuploaded-files/β
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd02h/64770d Inode: 96 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:unlabeled_t:s0
Access: 2018-08-02 09:53:04.532768235 +0100
Modify: 2018-08-02 09:52:58.664793452 +0100
Change: 2018-08-02 09:52:58.664793452 +0100
The volume looks like this inspected...
[
{
"Driver": "local",
"Labels": {
"com.docker.compose.project": "root",
"com.docker.compose.volume": "uploaded-files"
},
"Mountpoint": "/var/lib/docker/volumes/root_uploaded-files/_data",
"Name": "root_uploaded-files",
"Options": {},
"Scope": "local"
}
]
Does the container need to be started as a node user on the host?! I've used volumes with Solr for storing data on a volume and that has it's own user and not had this issue before.
I believe that the m,ounting in your docker compose replaces the permissions you set in the docker file with the ones from the volume. I am not too familiar with volumes, hopefully someone else faced something similar
@LaurentGoderre No worries, I think I've worked it out now using the below.
So I've added :rw to the end of the volume so now it looks like this.
volumes:
- /uploaded-files:/uploaded-files:rw
And the directory in the container kept the node user ownership and it's writing files on the volume fine now.
Yay! π
Good to know!!! Thanks for sharing!
Actually that doesn't seem to have worked.
So before doing the above I actually chown -R node:node /uploaded-files from within a running container and gave it to node user. I tested that and it worked.
I then seen the above so took down the containers in the usual manor, removed the volume.
Then just brought it up with the :rw added and just assumed that had worked.
But!!!! Then I tried it on another server and it didn't work... π So I've done the following:
Server B:
chown -R node:node /uploaded-files (as originally on Server A)docker exec -it app shls -lauploaded-files is owned by nodedocker-compose downdocker-compose and changed the service name e.g. from app to app-testdocker-compose up - so the container is now running under a different namedocker exec -it app shls -la uploaded-files is owned by nodeπ β
How is it still owned by node when this is a new container with a different service name?
So back to the original server I go...
Server A:
RUN mkdir /file-store && \
chown -R node:node /file-storedocker-compose.yml with new volume names volumes:
<ul>
<li>/file-store:/file-<a href="store:rw">store:rw</a><code>md5-bd5929635d28d11cb5d157cbb688e7b1</code>volumes:<br />
file-storedocker exec -it app shls -laSo that means the :rw on the volume didn't work. Okay but how did the directory in the different container on Server B still have the correct permissions after I stopped it?
So I then pointed the container dir to the original volume / host dir...
Server A:
docker-compose volume for the service to be volumes:
<ul>
<li>/uploaded-files:/file-<a href="store:rw">store:rw</a><code>md5-bd5929635d28d11cb5d157cbb688e7b1</code>volumes:<br />
uploaded-filesfile-store in the container is now mounted to uploaded-files on hostdocker exec -it app shls -la file-store inside the running container is now owned by user nodeSo that's new container, new service, new image ... but pointing to the original directory and some how it's go that chown -R node:node /uploaded-files which I did in a different container...
Now I admit I'm not a linux expert ... but what the?! My head hurts!
Are the different node users using different UUIDs? id node
@ntwrkguru Do you mean on the host? Should the host need to have a node user to actually execute docker-compose up? With the same uid & gid?
It doesn't need to be node but your own user should have user id 1000
The permissions of the host directory should match that of the user in the container. If it's UUID 1000, then on the host, chown 1000:1000 /some/host/dir
Ahhhh right okay.
So on the server there is already a user with an uid 1000.
uid=1000(linux_bkup) gid=1001(linux_bkup) groups=1001(linux_bkup),1000(beoper) - which I believe is from Backup Exec.
If I stat uploaded-files directory I get back
Access: (0755/drwxr-xr-x) Uid: ( 1000/linux_bkup) Gid: ( 1000/ beoper)
So after I chown -R node:node /uploaded-files earlier it's then given that host directory the same uid? Presume it's looking at the uid rather than the actual username then?
I've just tried to change the uid/gid of node user as per - https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#non-root-user
But get this error in Travis...
RUN mkdir /uploaded-files && \
chown -R node:node /uploaded-files && \
groupmod -g 500 node && \
usermod -u 500 -g 500 node

From your linked page:
If you need to change the uid/gid of the user you can use:
RUN groupmod -g 999 node && usermod -u 999 -g 999 node
In your Dockerfile, instead of RUN chown, simply declare a user and then create the dirs.
...
USER node
RUN groupmod -g 500 node && usermod -u 500 node
RUN mkdir /uploaded-files
...
Closing as answered
Most helpful comment
@LaurentGoderre No worries, I think I've worked it out now using the below.
https://stackoverflow.com/questions/50325494/how-can-i-change-permission-of-mounted-volumes-in-docker-compose-yml-from-the-do
So I've added
:rwto the end of the volume so now it looks like this.And the directory in the container kept the
nodeuser ownership and it's writing files on the volume fine now.Yay! π