Copy and chown files into a docker bind mount at runtime - 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.

Related

Bind mount file with destination relative to USER's home

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.)

Copy Directories through dockerfile with same privileges and ownership into the container

I have a directory and various files and directories inside that directory.
The ownership and group varies of some files directories.
I created a Dockerfile. I have created exactly the same user and group with the same uid and gid in Dockerfile.
So the container created will also have the same user and group with the same uid and gid as host.
The Image is built successfully as also container. When I See inside the container the ownership of all the directories and files are (root root).
I need the exact same ownership for each and every file and directory as of host.
Please help.
Thanks in advance.
the root user will be always the owner of the files after copying the files to the docker image.
It is a best practice to fix the file permission after copying or adding files to the Docker images.
ONBUILD ADD . /application
ONBUILD RUN chown -R rails /application
you don't need to care about the file owners on the host system, because all files will be available inside the docker container and the only thing that you should do is to make sure that the user running in the container has access rights to the files.
The only case that file permission need to be aligned between the host and the docker containers is the case where both the container and the host are sharing some files.

Docker on Google Compute Engine - How do I mount host directory with correct permissions

I'm using docker.io/solr:8.2.0 image on Google Compute Engine container instance, and have successfully got it running with a Mount path of /var/solr/data pointing to a Host path of /home/app/data
However, I'm having to do an extra step in the beginning to make /home/app/data writable by the container. I having to run in the host
sudo chown 8983:8983 /home/app -R
after that it works, /var/solr/data is mapped correctly and, on first run, even copies the files that are in the original /var/solr/data over to the host mount path
Is there a way to set this permission up in a start configuration so I can bypass this step?

Docker container volume has root only access

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.

How to give docker container write/chmod permissions on mapped volume?

I have a synology NAS which has docker support and wanted to run some docker containers (I'm pretty new to Docker) on it. For example pocketmine-pm (but I believe I have the write issue also with other containers).
I created a volume on the host and mapped this in the container settings. (And in the synology docker settings for the volume mapping I did not click on "read only").
According to the Dockerfile a new user 'pocketmine' is created inside the container and this user is used to start the server. The user seems to have the user ID 1000 (first UID for new linux users). The container also uses an Entrypoint.sh script to start the server.
Initially the container was not able to write files to the mapped directory. I had to SSH into the host 'chown' the directory for the UID 1000:
sudo chown 1000:1000 /volXy/docker/pocketminemp -R
After that the archive could be downloaded and extracted.
Unfortunately I was not able to connect to the server from my iOS device. The server is listed as 'online' but the connection fails without any specific message. I then checked the logs of the container and saw the following entries (not sure if this really prevents the connection but I will give it a try):
[*] Everything done! Run ./start.sh to start PocketMine-MP
chown: changing ownership of '/pocketmine/entrypoint.sh': Operation not permitted
chown: changing ownership of '/pocketmine/server.properties.original': Operation not permitted
Loading pocketmine.yml...
Apparently the container cannot chown a file it was previously able to download.
Does anybody know what can be done to fix this? Do I need to chmod the mapped volume and why did I need to chown the directory to UID 1000 (a user that doesn't really exist on the host) - isn't there a more elegant way to fix the permissions?
When you run the container, you should be able to use the --user="uid:gid" flag to specify the user you wish to run the container as.
Source: https://docs.docker.com/engine/reference/run/#user

Resources