What does a docker read only mount mean in docker? - docker

The relevant documentation
https://docs.docker.com/storage/bind-mounts/
says
For some development applications, the container needs to write into
the bind mount, so changes are propagated back to the Docker host. At
other times, the container only needs read access.
This example modifies the one above but mounts the directory as a
read-only bind mount, by adding ro to the (empty by default) list of
options, after the mount point within the container. Where multiple
options are present, separate them by commas.
I expect that to mean that there is no way to write to the folder that is mounted in that way from within the container. But if I minimally modify the example to give me a shell session and mount the root filesystem
~ $ docker run \
-it \
--name devtest2 \
--mount type=bind,source=/,target=/app,readonly \
ubuntu:latest
I see that I have write access as root from to the entirety of the host filesystem from within the container.
root#bde1f19c1de2:/# cd /app/home/
# Creates directory in the host /home folder
root#bde1f19c1de2:/app/home# mkdir patata
What does then mean that the mount is "readonly".
How do I make it actually read-only?
I observe this behavior with docker 17.05 as it comes with Ubuntu trusty:
$ docker --version
Docker version 17.05.0-ce, build 89658be

I don't know how you can use --mount option as it is only available for standalone container from Docker 17.06 and yours is 17.05.
Ref
Originally, the -v or --volume flag was used for standalone containers
and the --mount flag was used for swarm services. However, starting
with Docker 17.06, you can also use --mount with standalone
containers. In general, --mount is more explicit and verbose. The
biggest difference is that the -v syntax combines all the options
together in one field, while the --mount syntax separates them. Here
is a comparison of the syntax for each flag.
That said i tried it out on docker 17.09 and still saw the same result as your decribed. Only to realise that the "readonly" option is working but your linux permissions are as such which is allowing anyone to write on it!
Since you are mounting / and writing to home directory which has 0755 permission by default
0755 means public (anyone) read and execute. The execute is allowing you to execute the mkdir command
If you mount paths or folder which doesn't have public access then you will see the readonly option works irrective of it being a root user or not inside the container, which is you wont be allowed to write!
example I am mounting home directory which has a 0770 which is public doesn't have any access!
[root#jakku-admin-1 ~]# pwd
/root
[root#jakku-admin-1 ~]# ll
total 8
drwxr-xr-x. 2 root root 4096 Feb 7 21:19 archive
drwxrwx---. 2 root root 4096 Feb 7 20:38 home
[root#jakku-admin-1 ~]# docker run -it --name devtest --mount type=bind,source=`pwd`/home,target=/app,readonly ubuntu:latest
root#3ce55bba8904:/# ll
total 16
drwxr-xr-x. 22 root root 253 Feb 7 21:20 ./
drwxr-xr-x. 22 root root 253 Feb 7 21:20 ../
-rwxr-xr-x. 1 root root 0 Feb 7 21:20 .dockerenv*
drwxrwx---. 2 root root 4096 Feb 7 20:38 app/
drwxr-xr-x. 2 root root 4096 Jan 12 21:10 bin/
drwxr-xr-x. 2 root root 6 Apr 24 2018 boot/
drwxr-xr-x. 5 root root 360 Feb 7 21:20 dev/
drwxr-xr-x. 29 root root 4096 Feb 7 21:20 etc/
drwxr-xr-x. 2 root root 6 Apr 24 2018 home/
drwxr-xr-x. 8 root root 96 May 23 2017 lib/
drwxr-xr-x. 2 root root 34 Jan 12 21:10 lib64/
drwxr-xr-x. 2 root root 6 Jan 12 21:09 media/
drwxr-xr-x. 2 root root 6 Jan 12 21:09 mnt/
drwxr-xr-x. 2 root root 6 Jan 12 21:09 opt/
dr-xr-xr-x. 592 root root 0 Feb 7 21:20 proc/
drwx------. 2 root root 37 Jan 12 21:10 root/
drwxr-xr-x. 5 root root 58 Jan 16 01:20 run/
drwxr-xr-x. 2 root root 4096 Jan 16 01:20 sbin/
drwxr-xr-x. 2 root root 6 Jan 12 21:09 srv/
dr-xr-xr-x. 13 root root 0 Jan 29 22:42 sys/
drwxrwxrwt. 2 root root 6 Jan 12 21:10 tmp/
drwxr-xr-x. 10 root root 105 Jan 12 21:09 usr/
drwxr-xr-x. 11 root root 139 Jan 12 21:10 var/
root#3ce55bba8904:/# cd app/
root#3ce55bba8904:/app# ll
total 4
drwxrwx---. 2 root root 4096 Feb 7 20:38 ./
drwxr-xr-x. 22 root root 253 Feb 7 21:20 ../
root#3ce55bba8904:/app# mkdir test
mkdir: cannot create directory 'test': Read-only file system
root#3ce55bba8904:/app# touch test
touch: cannot touch 'test': Read-only file system

Related

Docker: file permissions with --volume bind mount

I'm following the guidelines from: https://denibertovic.com/posts/handling-permissions-with-docker-volumes/ to setup a --volume bind mount in my container and creating a user in the guest container with the same UID as my host user - the theory being that my container user should be able to access the mount. It's not working for me and I'm looking for some pointers to try next.
More background details:
My Dockerfile starts from an alpine base and adds python dev packages. It copies across an entrypoint.sh script per guidelines from denibertovic. It then jumps to the entrpoint.sh script.
FROM alpine
RUN apk update
RUN apk add bash
RUN apk add python3
RUN apk add python3-dev
RUN apk add su-exec
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
The entrpoint.sh script adds a user to the container with the UID passed in as an environment variable.
#!/bin/bash
# Add local user
# Either use the LOCAL_USER_ID if passed in at runtime or
# fallback
USER_ID=${LOCAL_USER_ID:-9001}
echo "Starting with UID : $USER_ID"
adduser -s /bin/bash -u $USER_ID -H -D user
export HOME=/home/user
su-exec user "$#"
The container builds no problem.
I then run it with the following command line:
sudo docker run -it -e LOCAL_USER_ID=`id -u` -v `realpath ../..`:/ws django-runtime /bin/bash
You'll see that I'm passing in my host UID to be mapped to the container user's UID and I'm asking for a volume bind mount from my local working directory to the /ws mountpoint in the container.
From the bash shell inside the container I can see that /ws is owned by the 'user' UID matching my own 'id'. However, when I go to list the contents of /ws I get a Permission Denied error as follows:
[dleclair#localhost runtime]$ sudo docker run -it -e LOCAL_USER_ID=`id -u` -v `realpath ../..`:/ws django-runtime /bin/bash
[sudo] password for dleclair:
Starting with UID : 1000
bash-5.0$ id
uid=1000(user) gid=1000(user) groups=1000(user)
bash-5.0$ ls -la .
total 0
drwxr-xr-x 1 root root 27 Feb 8 09:15 .
drwxr-xr-x 1 root root 27 Feb 8 09:15 ..
-rwxr-xr-x 1 root root 0 Feb 8 09:15 .dockerenv
drwxr-xr-x 1 root root 18 Feb 8 07:44 bin
drwxr-xr-x 5 root root 360 Feb 8 09:15 dev
drwxr-xr-x 1 root root 91 Feb 8 09:15 etc
drwxr-xr-x 2 root root 6 Jan 16 21:52 home
drwxr-xr-x 1 root root 17 Jan 16 21:52 lib
drwxr-xr-x 5 root root 44 Jan 16 21:52 media
drwxr-xr-x 2 root root 6 Jan 16 21:52 mnt
drwxr-xr-x 2 root root 6 Jan 16 21:52 opt
dr-xr-xr-x 119 root root 0 Feb 8 09:15 proc
drwx------ 2 root root 6 Jan 16 21:52 root
drwxr-xr-x 1 root root 21 Feb 8 07:44 run
drwxr-xr-x 1 root root 21 Feb 8 08:22 sbin
drwxr-xr-x 2 root root 6 Jan 16 21:52 srv
dr-xr-xr-x 13 root root 0 Feb 8 01:58 sys
drwxrwxrwt 2 root root 6 Jan 16 21:52 tmp
drwxr-xr-x 1 root root 19 Feb 8 07:44 usr
drwxr-xr-x 1 root root 19 Jan 16 21:52 var
drwxrwxr-x 5 user user 111 Feb 8 02:15 ws
bash-5.0$
bash-5.0$
bash-5.0$ cd /ws
bash-5.0$ ls -la
ls: can't open '.': Permission denied
total 0
bash-5.0$
Appreciate any pointers anyone can offer. Thanks!
After more searching I found the answer to my problem here: Permission denied on accessing host directory in Docker and here: http://www.projectatomic.io/blog/2015/06/using-volumes-with-docker-can-cause-problems-with-selinux/.
In short, the problem was with the SELinux default labels for the volume mount blocking access to the mounted files. The solution was to add a ':Z' trailer to the -v command line argument to force docker to set the appropriate flags against the mounted files to allow access.
The command line therefore became:
sudo docker run -it -e LOCAL_USER_ID=`id -u` -v `realpath ../..`:/ws:Z django-runtime /bin/bash
Worked like a charm.

creating my own docker image for archlinux and how to use it for development

I am trying to learn docker. So i am trying to create an archlinux image. Presently i am not worried of size. But i am stuck up how to further go ahead to use this as my development for a project. My goal is to create and use different archlinux images for my different projects separately.
1) shift to root in terminal
2) mkdir archlinux
3) pacstrap -i -c -d ./archlinux base
4) echo 'en_US.UTF-8 UTF-8' > ./archlinux/etc/locale.gen
5) arch-chroot ./archlinux locale-gen
6) echo 'LANG=en_US.UTF-8' > ./archlinux/etc/locale.conf
Now the total size of the folder archlinux is 899 MB.
Now i am trying to import it as an docker image
cd archlinux
tar -c . | docker import - example_archlinux
tar: ./etc/pacman.d/gnupg/S.gpg-agent: socket ignored
tar: ./etc/pacman.d/gnupg/S.gpg-agent.extra: socket ignored
tar: ./etc/pacman.d/gnupg/S.gpg-agent.ssh: socket ignored
tar: ./etc/pacman.d/gnupg/S.scdaemon: socket ignored
tar: ./etc/pacman.d/gnupg/S.gpg-agent.browser: socket ignored
sha256:2b3ed6536389a1184f402ff5a9d20380a3f4aa2c49bdee31df9c7c10186eb889
Now I run the docker image
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
example_archlinux latest 2b3ed6536389 About a minute ago 881MB
Now i try to run the image:
# docker run -ti example_archlinux:latest /bin/bash
[root#3863ba31186b /]#
# docker run -ti example_archlinux:latest ls -al
total 52
drwxr-xr-x 1 root root 4096 Oct 16 08:32 .
drwxr-xr-x 1 root root 4096 Oct 16 08:32 ..
-rwxr-xr-x 1 root root 0 Oct 16 08:32 .dockerenv
lrwxrwxrwx 1 root root 7 Jan 5 2018 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Oct 16 08:01 boot
drwxr-xr-x 5 root root 360 Oct 16 08:32 dev
drwxr-xr-x 1 root root 4096 Oct 16 08:32 etc
drwxr-xr-x 2 root root 4096 Jan 5 2018 home
lrwxrwxrwx 1 root root 7 Jan 5 2018 lib -> usr/lib
lrwxrwxrwx 1 root root 7 Jan 5 2018 lib64 -> usr/lib
drwxr-xr-x 2 root root 4096 Jan 5 2018 mnt
drwxr-xr-x 2 root root 4096 Jan 5 2018 opt
dr-xr-xr-x 275 root root 0 Oct 16 08:32 proc
drwxr-x--- 3 root root 4096 Oct 16 08:01 root
drwxr-xr-x 2 root root 4096 Oct 16 08:01 run
lrwxrwxrwx 1 root root 7 Jan 5 2018 sbin -> usr/bin
drwxr-xr-x 4 root root 4096 Oct 16 08:01 srv
dr-xr-xr-x 13 root root 0 Oct 16 08:32 sys
drwxrwxrwt 2 root root 4096 Oct 16 08:01 tmp
drwxr-xr-x 8 root root 4096 Oct 16 08:10 usr
drwxr-xr-x 12 root root 4096 Oct 16 08:01 var
Its great. Its working
Q1 : Will docker not ask for login and password of root, assuming i have set root passwd
I want to create my Django + ngingx + postgresql + redis + git. I will install and setup the required packages.
.
So i am testing whether run command will save the folders craeted
# docker run -ti example_archlinux:latest /bin/bash
[root#9f4e56ce38c5 /]# mkdir hare
[root#9f4e56ce38c5 /]# exit
# docker run -ti example_archlinux:latest ls /hare
ls: cannot access '/hare': No such file or directory
I have the main question:
Q2 Since i created a folder and if i exit its not there anymore.
Now what is the best way to use a docker image for my development.
I cant afford that my files are not there after i exit.
So is there any way that the container is permanently created and i can work in it for my development.
OR
Where to create my source code on host or docker. I want everything at one place.
Q1: I never tried setting the root password. But usually, when running the container, you'll be logged in as root except if you use the USER Dockerfile command, which is the more secure approach. More about it here
Q2: Everytime you remove your container, everything inside of it will be destroyed. So, you'll lose the files you've created, unless you bound a volume to your host. Volumes are the standard way to go. You can define a volume, for instance, on your docker run command:
docker run -ti -v /host/source/folder:/desired/guest/folder example_archlinux:latest ls -al
Now you can add/remove/change files both from container or host and it will be persisted. There wont be duplicated files. It's just that both have access to it.
more details here

/bin/sh: app: not found

/ # which chasquid-util
/usr/local/bin/chasquid-util
/ # chasquid-util
/bin/sh: chasquid-util: not found
/ # /usr/local/bin/chasquid-util
/bin/sh: /usr/local/bin/chasquid-util: not found
/ # ls -al /usr/local/bin/
total 27432
drwxr-xr-x 1 root root 4096 Jul 26 16:18 .
drwxr-xr-x 1 root root 4096 Jul 26 16:18 ..
-rwxr-xr-x 1 root root 11721005 Jul 26 16:18 chasquid
-rwxr-xr-x 1 root root 5510494 Jul 26 16:18 chasquid-util
-rwxr-xr-x 1 root root 2910713 Jul 26 16:18 mda-lmtp
-rwxr-xr-x 1 root root 4767277 Jul 26 16:18 smtp-check
-rwxr-xr-x 1 root root 3164845 Jul 26 16:18 spf-check
/ #
Given your context, this typically means you are missing a shared library. With alpine, it's typically glibc since they ship with libmusl. You can check this with:
ldd chasquid-util
I've got several other reasons for this listed in my DC 2018 slidedeck:
Did you run the intended command? (e.g. docker run --rm my_image -it echo hello world will run the command -it)
Is docker trying to run a json string? (any json paring errors will show up as executing the json as a string)
Does the file exist... in the path and inside the container? (can't run stuff from the host inside a container without building it into the image or mounting a volume)
If it is a shell script, check the first line (e.g. #!/bin/bash)
Check for windows linefeeds on linux shell scripts (look for ^M or \r with different editors)
If it is a binary, there is likely a missing library (use ldd to check)

docker cp - "Error response from daemon: not a directory"

I am trying to copy file from docker to host using the below command,
docker cp <container_name>:<file FQN> ./
But getting the below error,
Error response from daemon: not a directory
As verified, the file name and container name are valid.
Note: Using Docker in Mac
Thanks for all the answers. After a bit of struggle found out that the error message was not actually directly related to the docker cp command.
The scenario was, I ran the docker with the link to a local file. When the docker was running I deleted it. Then the file got created as a folder somehow (Probably, when I restarted the docker).
And whenever I am executing some command, the docker was giving me that error. Then once I created the file the error disappeared.
It seems your command is correct. You please try like the below from your local machine not from inside the container. sometimes unfortunately if we run this command with in the container we will get this kind of errors.
docker cp [container_name]:[docker dir abs path] [host dir path]
Hope it will help you.
Here is a full example on how to copy a file:
$ docker run -it ubuntu /bin/bash
root#9fc8a1af7f23:/#
root#9fc8a1af7f23:/# ll
total 72
drwxr-xr-x 34 root root 4096 Jul 13 21:51 ./
drwxr-xr-x 34 root root 4096 Jul 13 21:51 ../
-rwxr-xr-x 1 root root 0 Jul 13 21:51 .dockerenv*
drwxr-xr-x 2 root root 4096 Feb 14 23:29 bin/
drwxr-xr-x 2 root root 4096 Apr 12 2016 boot/
drwxr-xr-x 5 root root 360 Jul 13 21:51 dev/
drwxr-xr-x 45 root root 4096 Jul 13 21:51 etc/
drwxr-xr-x 2 root root 4096 Apr 12 2016 home/
drwxr-xr-x 8 root root 4096 Sep 13 2015 lib/
drwxr-xr-x 2 root root 4096 Feb 14 23:29 lib64/
drwxr-xr-x 2 root root 4096 Feb 14 23:28 media/
drwxr-xr-x 2 root root 4096 Feb 14 23:28 mnt/
drwxr-xr-x 2 root root 4096 Feb 14 23:28 opt/
dr-xr-xr-x 288 root root 0 Jul 13 21:51 proc/
drwx------ 2 root root 4096 Feb 14 23:29 root/
drwxr-xr-x 6 root root 4096 Feb 27 19:41 run/
drwxr-xr-x 2 root root 4096 Feb 27 19:41 sbin/
drwxr-xr-x 2 root root 4096 Feb 14 23:28 srv/
dr-xr-xr-x 13 root root 0 Jul 13 21:51 sys/
drwxrwxrwt 2 root root 4096 Feb 14 23:29 tmp/
drwxr-xr-x 11 root root 4096 Feb 27 19:41 usr/
drwxr-xr-x 13 root root 4096 Feb 27 19:41 var/
root#9fc8a1af7f23:/# cd tmp/
root#9fc8a1af7f23:/tmp# ls
root#9fc8a1af7f23:/tmp# echo "hello docker" > docker_test.txt
root#9fc8a1af7f23:/tmp# cat docker_test.txt
hello docker
root#9fc8a1af7f23:/tmp#
Then, in another terminal
dali#dali-X550JK:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc8a1af7f23 ubuntu "/bin/bash" 2 minutes ago Up 2 minutes fervent_hodgkin
dali#dali-X550JK:~$ docker cp fervent_hodgkin:/tmp/docker_test.txt /tmp/
dali#dali-X550JK:~$ cat /tmp/docker_test.txt
hello docker
dali#dali-X550JK:~$
Please follow these instruction, make sure your don't have typo in the file paths, otherwise share a reproducible error.
This error also appears when trying to copy a file that is actually a volume in the container, but the file has been deleted on the host.
This is simply an error in the path you want to copy.
You may not believe it, but that it is.

Docker run with "-v" create another shared directory

I have a strange problem running a Docker container
It is working OK if I run:
docker run -it -v /home/drleo/pythonCourses:/home/pythonCurses /redpmorg/python-courses
But if I run container with publish option the Docker will create a new folder in my /home/drleo directory with the SAME name: pythonCourses, owned by root but obviously empty:
docker run -it -p 127.0.0.1:8080:8080 -v /home/drleo/pythonCourses:/home/pythonCurses /redpmorg/python-courses
-rw-r--r-- 1 drleo drleo 675 May 6 2016 .profile
drwxr-xr-x 2 drleo drleo 4096 May 6 2016 Public
drwxr-xr-x 2 root root 4096 Feb 16 13:08 pyhtonCourses
drwxrwxr-x 2 drleo drleo 4096 Feb 16 13:08 pythonCourses
-rwxrwxr-x 1 drleo drleo 71 Jan 20 22:35 reset-network
The question is why? Thanks!
You seem to have a type somewhere. python != pyhton.
Double check your command history.

Resources