I am trying to start containers as non root user. The volume which is being generated has root only access. The non root user of container is unable to write in the volume directory of the container.
docker-compose.yml
volumes:
- ./trm/workspace:/opt/kad/translation/workspace
Dockerfile:
RUN chown -R nonrootuser /opt/kad/translation/workspace
VOLUME /opt/kad/translation-resource-monitor/workspace
Is there any way to create the volume with write access to non root user.
Volumes are not generated but mounted with host privileges. Also Dockerfile directives are executed on image build which is before you run a container. In your case /opt/kad/translation/workspace directory owned by nonrootuser user is being replaced by ./trm/workspace owned by the same uid/gid as on the host when container is started. So you need to make sure the host folder has correct permissions before running the container, e. g:
chown -R uid_of_nonrootuser_in_container:gid_of_nonrootuser_in_container \
./trm/workspace && docker-compose up -d
Note that there are different users on host and in container so you should use uid and gid of the container user, not it's username and group name. To find uid and gid run id nonrootuser in container.
Another solution (as Manish Joshi pointed out) is to make the directory writable for all users:
chmod -R 0777 ./trm/workspace
But it gives you less control of the folder's security.
Related
How to set ownership and permissions of a file mounted via a docker volume
We want to set the ownership of files mounted by a volume to a user within the container using chown command and similarly set permissions using chmod command. How to do this
volumes:
- $PWD/foo.pem:/opt/conf/foo.pem
- $PWD/bar.pem:/opt/conf/bar.pem
You need to find out uid and gui of the container user with id username in container. Then chown uid:gid foo.pem outside of container.
I use build-arg to ensure my container runs with the same UID as my host user:
--build-arg UID=$(UID)
I am mounting a volume with:
-v $(PWD)/packages:/mnt/packages
Because I want my container to produce some output into that directory.
The directory belongs to the host user.
But, not matter what I try, the mountpoint in the container belongs to root. I can correct it with sudo in the running container:
function correct-mountpoint-permissions () {
# Hack alert:
# When mounting a host volume, it belongs to root, no matter what I do in the host or in the Dockerfile
# Here we correct the situation by using sudo. It's not nice, but that's life
# Note: the same problem does NOT happen with *named* volumes, but that completely defeats the purpose of
# mounting the volume in the first place - which is to produce some output visible on the host.
# If I have to start copying from containers to host, mounting volumes offers no benefit
sudo chown "$USER:$USER" "$PACKAGES"
}
But this is just ugly. I should not even need to have sudo installed in the first place, or sudo rights at all in my container.
The alternative is to either mount a named volume, which is difficult to access from the host, or to avoid mounting volumes in the container at all, and just docker cp from it when my container has produced the expected output.
Is there a simple way of mounting a host volume with the right ownership into a container (which means, not root, but my selected UID)
I understand you must be setting a user in your Dockerfile.
Before the user is set , try changing the ownership of the user during the build of the image.
RUN chown -R myuser:myuser ${PACKAGES_DIR}
USER myuser
I have a Dockerfile which specifies a USER and executes a script as that user. The script requires an file mounted in that user's home directory. Assuming I don't know what that user is or what its home directory is (and want to keep it dynamic instead of using docker inspect and manually entering it), is it possible to mount a file in the container with the destination being relative to USER's home?
i.e. docker run -v $PWD/file:somedir/file <image>
where $PWD/file on the host ends up mounted at ~USER/somedir/file in the container.
This currently gives docker: Error response from daemon: invalid volume specification: '$PWD/file:somedir/file': invalid mount config for type "bind": invalid mount path: 'somedir/file' mount path must be absolute.
Docker images generally have a fixed filesystem layout. They don't typically have "multiple users", "home directories", or variable paths, the way you might on a standard server setup.
For the sort of setup you describe, I might suggest:
Install your application in some easy-to-find directory like /app. (Pick a path; don't have it be an environment variable.)
Have the application and its files be owned by root and not world-writeable.
Have the image install some non-root user. It doesn't matter what that user is, and it doesn't need to match any particular host user.
The application should expect some easy-to-find directory like /data.
When you run the application, specify both the host user ID and the content to mount on /data.
FROM ???
WORKDIR /app
COPY . . # will be owned by root (and that's okay)
RUN adduser user # can be any name and any non-0 uid
RUN mkdir /data && chown user /data
ENV DATA_DIR=/data # to tell the application where it is
USER user
CMD ["/app/the_application"]
sudo docker run --rm \
-v "$PWD/content":/data \
-u $(id -u) \
the-image
It's important to keep the application and data separate, so that the bind-mount doesn't overwrite the application data. You wouldn't usually pass any host-specific data into the build process so that the built image can be reused in different environments.
(If the application is really just a script, it's not a long-running process, and the single important thing it does is manipulate files in the user's home directory, you might find just distributing the script to be much easier than trying to run it via Docker.)
I have nginx and wordpress in docker containers, which share a volume bind mount (i.e. mapped to files on disk) for /var/www/html.
At runtime I need to add files to the mapped directory, chown them, and for them to be usable. They appear in the volume, but their owner is wrong so they are unusable by nginx / wordpress.
(Typically the advice is to do this in the Dockerfile - but that doesn't apply in this case. I'm not modifying the app, I'm just adding to the volume, which is not ephemeral.)
When I stop and start the docker apps (nginx and wordpress), everything works. But it doesn't work while online.
The parent directory has chmod 2775 and chown -R bob:www-data. When I copy files in there at runtime, I am doing so as bob. But nginx still cannot access those new files (404).
So how do I copy and chown files into a bind mount at runtime?
You should check that you are not only using the same username, but also the same UID & GID (If you have the user bob both in docker and the host but UID & GID don't match you will get permissions issues).
There is a good explanation on that on this other post.
I've dockerized a PHP application using a data-only container. I used this (docker-symfony) containers stack.
This is a simple definition of a data-only container:
FROM debian:jessie
MAINTAINER Vincent Composieux <vincent.composieux#gmail.com>
VOLUME /var/www/symfony
Everything plays really well apart from ownership and permissions. I've noticed that when I mount volumes (my local directory) to the data-only container, the mounted files remain owned by my current user on the host, which in not recognized inside the container.
For example, If I'm starting the containers with docker-compose up as ltarasiewicz, and then I log into the data container, I can see that the mounted files have ownership set to:
drwxrwxr-x 7 1000 1000 4096 Jun 10 21:27 symfony
uid and gid of 1000 correspond to my host's user uid and gid. Because there is no such user inside the container, only IDs are displayed for the symfony directory. This makes it impossible to run the application.
So my question is how I can mount volumes to a data-only container and assign correct ownership to the mounted files, e.g. root:www-data or whatever other users I choose.
Use the same image you use for running the application to make your data container. For example, if you want to make a postgresql database, use the postgres image for your data container:
$ docker run --name dc postgres echo "Data Container"
This command created the data container and exited - note that data containers aren't left running.
In the case of postgres, the volume ownership won't be set correctly until you use the volume to start a db:
$ docker run -d --volumes-from dc postgres
But other images will set up the ownership correctly in the Dockerfile.
Of course, if you just want to fix the permissions in a data container, just mount it and run chown:
$ docker run --volumes-from dc postgres chown -R postgres:postgres /var/lib/postgresql/data