I am trying to run a container with volume and customized entry point, and then execute a .sh script inside the volume I shared from the docker command.
I have a folder inside my primary machine on that location: ~/vol, and inside I have a script that I want to execute on the container.
[root#ilcepoc2457 vol]# pwd
/root/vol
[root#ilcepoc2457 vol]# ll
total 8
-rwxrwxrwx. 1 root root 17 Jan 29 17:11 startup.sh
dr-xr-x---. 14 root root 4096 Jan 29 17:11 ..
drwxr-xr-x. 2 root root 24 Jan 29 17:11 .
I am trying to create a container using this command:
docker run -i -t -d --volume /vol:/vol --entrypoint "/startup.sh" mcr.microsoft.com/playwright
And this is the error I get:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/startup.sh": stat /startup.sh: no such file or directory: unknown.
What am I missing here?
The directory you show is /root/vol, but you map /vol.
Your directory is mapped to the /vol directory, but your entrypoint /startup.sh says that it's in the root of the file system. Use /vol/startup.sh instead, like this
docker run -i -t -d --volume /root/vol:/vol --entrypoint "/vol/startup.sh" mcr.microsoft.com/playwright
Related
Docker version 20.10.2
I'm just starting out on Docker and following training guides - but something hasn't been mentioned so far (that I have discovered) - when I run a container to write some data out to Docker volume, if I run that container again and attach to the same volume, the newly named data will not append into it ?
Here is my rather basic Dockerfile
FROM ubuntu
RUN mkdir applocal
RUN touch applocal/applocalfile."$(date --iso-8601=seconds)"
RUN ls -la applocal
I run this sequence of commands...
docker build Dockerfile -t mine/applocal-persist
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM ubuntu
---> c29284518f49
Step 2/4 : RUN mkdir applocal
---> Running in 9f796f4d988a
Removing intermediate container 9f796f4d988a
---> 99005a7ffed1
Step 3/4 : RUN touch applocal/applocalfile."$(date --iso-8601=seconds)"
---> Running in ffbf2f4c636a
Removing intermediate container ffbf2f4c636a
---> 199bc706dcc6
Step 4/4 : RUN ls -la applocal
---> Running in 7da02faa9fba
total 8
drwxr-xr-x 1 root root 4096 Jul 16 13:52 .
drwxr-xr-x 1 root root 4096 Jul 16 13:52 ..
-rw-r--r-- 1 root root 0 Jul 16 13:52 applocalfile.2021-07-16T13:52:00+00:00
Removing intermediate container 7da02faa9fba
---> 7387c521d82b
Successfully built 7387c521d82b
Successfully tagged mine/applocal-persist:latest
Then run the command...
docker run -v applocalsaved:/applocal mine/applocal-persist
Looking at the Volume data it has worked
ls -la /var/lib/docker/volumes/applocalsaved/_data/
total 8
drwxr-xr-x 2 root root 4096 Jul 16 14:55 .
drwxr-xr-x 3 root root 4096 Jul 16 14:55 ..
-rw-r--r-- 1 root root 0 Jul 16 14:52 applocalfile.2021-07-16T13:52:00+00:00
If I wait a few minutes later and re-run docker run -v applocalsaved:/applocal mine/applocal-persist
...and check the volume data again, no new file exists
ls -la /var/lib/docker/volumes/applocalsaved/_data/
total 8
drwxr-xr-x 2 root root 4096 Jul 16 14:55 .
drwxr-xr-x 3 root root 4096 Jul 16 14:55 ..
-rw-r--r-- 1 root root 0 Jul 16 14:52 applocalfile.2021-07-16T13:52:00+00:00
Run history...
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d16e9aa495e mine/applocal-persist "bash" 57 seconds ago Exited (0) 55 seconds ago distracted_cohen
69ff06d9c886 mine/applocal-persist "bash" 2 minutes ago Exited (0) 2 minutes ago affectionate_lehmann
I've listed the Volume Inspect here...
docker volume inspect applocalsaved
[
{
"CreatedAt": "2021-07-16T14:55:24+01:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/applocalsaved/_data",
"Name": "applocalsaved",
"Options": null,
"Scope": "local"
}
]
I'm obviously missing a trick here - or misunderstanding what is going on or the design around this.
Thanks in advance
For info: I'm using Windows running Virtual Box and running Ubuntu 21.04 as a VM
Those commands run once when the image is built.
If you want something to run on container startup, you can use CMD or ENTRYPOINT
https://docs.docker.com/engine/reference/builder/#cmd
https://docs.docker.com/engine/reference/builder/#entrypoint
The commands in the Dockerfile only run once, when the image is originally built. You can verify this for example by just running the image without a volume mount:
docker build -t mine/applocal-persist .
docker run --rm mine/applocal-persist \
ls -l ./applocal
sleep 60
docker run --rm mine/applocal-persist \
ls -l ./applocal
If you start the container with a named volume mounted, only if the volume is a Docker named volume and only if the volume is empty, the contents of the image will be copied into the volume. (This doesn't happen on Docker bind mounts, Kubernetes volumes, or if the image has changed; I would not rely on this for any sort of data sharing since it works in so few contexts.)
Conversely, if you start the container with any sort of volume mounted, whatever content is in the volume completely replaces what's in the image. You can see this with some more experimentation:
# Build the image
docker build -t mine/applocal-persist
# Start the container with a new named volume mounted; see what's there.
docker volume rm applocalsaved
docker run --rm -v applocalsaved:/applocal mine/applocal-persist \
ls -l /applocal
# Edit a file in the volume and see that it gets persisted across restarts
docker run --rm -v applocalsaved:/applocal mine/applocal-persist \
touch /applocal/foo
docker run --rm -v applocalsaved:/applocal mine/applocal-persist \
ls -l /applocal
# But it is not included in the image without the bind mount
docker run --rm mine/applocal-persist \
ls -l /applocal
sleep 60
# Rebuild the image
docker build -t mine/applocal-persist
# In the base image, you will see the updated timestamp
docker run --rm mine/applocal-persist \
ls -l /applocal
# But if you mount the volume, the old volume contents replace the
# image contents and you will only see the old timestamp
docker run --rm -v applocalsaved:/applocal mine/applocal-persist \
ls -l /applocal
I want to use a custom docker config.json file like this to reassign the detach keystrokes:
{
"detachKeys": "ctrl-q,ctrl-q"
}
In a "normal" docker world, i.e. one where docker is installed via apt or similar and not snap, I could put this file in $HOME/.docker/config.json and the setting is picked up when I next run the docker command. However, this file is not recognized when running /snap/bin/docker. docker just silently ignores it.
If I try to force it to use this directory, I am denied:
$ docker --config .docker/ run -it ubuntu /bin/bash
WARNING: Error loading config file: .docker/config.json: open .docker/config.json: permission denied
If I try to locate the file alongside daemon.json in /var/snap/docker/current/config/ this also silently fails to notice any config.json:
$ ls -l /var/snap/docker/current/config/
total 8
-rw-r--r-- 1 root root 36 Feb 28 11:28 config.json
-rw-r--r-- 1 root root 200 Feb 28 09:44 daemon.json
$ docker run -it ubuntu /bin/bash
Now, I can force the directory location, but surely there is a better way?
$ docker --config /var/snap/docker/current/config/ run -it ubuntu /bin/bash
Ok, after writing this question, I ran across the answer. Snap wants this file to go here:
$ ls -l ~/snap/docker/current/.docker/
total 4
-rw-r--r-- 1 gclaybur gclaybur 36 Feb 28 12:04 config.json
I'm trying to understand when containers copy preexisting files into a mounted volume on the same directory. For example
FROM ubuntu
RUN mkdir /testdir
RUN echo "Hello world" > /testdir/file.txt
running:
#docker create volume vol
#docker run -dit -v vol:/testdir myimage
#docker exec -it 900444b7ab86 ls -la /testdir
drwxr-xr-x 2 root root 4096 May 11 18:43 .
drwxr-xr-x 1 root root 4096 May 11 18:43 ..
-rw-r--r-- 1 root root 6 May 11 17:53 file.txt
The image for example also has files in:
# docker exec -it 900444b7ab86 ls -la /etc/cron.daily
total 20
drwxr-xr-x 2 root root 4096 Apr 26 21:17 .
drwxr-xr-x 1 root root 4096 May 11 18:43 ..
-rwxr-xr-x 1 root root 1478 Apr 20 10:08 apt-compat
-rwxr-xr-x 1 root root 1176 Nov 2 2017 dpkg
-rwxr-xr-x 1 root root 249 Jan 25 15:09 passwd
But for example when I run it with
docker run -it 900444b7ab81 -v vol:/etc/cron.daily
The directory is now empty..
Why don't the files get copied this time?
#docker run -dit -v vol:/testdir
That is not a valid docker command, there's no image reference included, so there's nothing for docker to run.
docker run -it 900444b7ab81 -v vol:/etc/cron.daily
This will attempt to run the image 900444b7ab81 with the command -v vol:/etc/cron.daily. Before you had a container id with a very similar id, so it's not clear that you aren't trying to do a run with a container id instead of an image id. And the command -v likely doesn't exist inside the container.
The order of these arguments is important, the first thing after the run that isn't an option or arg to the previous option is treated as the image reference. After that reference, anything else passed is a command to run in the container. So if you wanted to mount the volume, you need to move that option before the image id.
I'm trying to understand when containers copy preexisting files into a mounted volume on the same directory.
With named volumes, docker initializes an empty named volume upon creation of the container with the contents of the image at that location. Once the volume has files in it, it will be mapped as is into the container on any subsequent usage, so changes to the image at the same location will not be seen.
I have just started to use docker. I have installed alpine image for testing docker workflow but after running
docker run alpine ls -l
I am getting this following error
Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"ls-l\": executable file not
found in $PATH".
I have installed Docker Desktop for Windows in Windows 10.
The last argument to docker run must be the name of an executable. ls is a command implemented by the shell, but not an executable in itself, hence the error you see. You have to tell docker to run ls in the context of a particular shell. E.g.
$ docker run alpine sh -c 'ls -l'
total 52
drwxr-xr-x 2 root root 4096 Oct 25 22:05 bin
drwxr-xr-x 5 root root 340 Nov 15 22:45 dev
drwxr-xr-x 14 root root 4096 Nov 15 22:45 etc
...
Hope this helps.
Here is part of my Dockerfile :
RUN mkdir /data
RUN chown www-data:www-data /data
RUN chmod 664 /data
VOLUME ["/data"]
I create the image with the command :
docker build -t webapp .
I run it like this :
docker run -d -p 80:80 -v /home/user/data:/data webapp
But in my host user dir, the data directory is created like this :
drwxr-xr-x 2 root root 4,0K avril 28 21:52 data
And in the image (docker exec -it CONTAINER_ID bash) i have :
drwxr-xr-x 2 root root 4096 Apr 28 19:52 data
So commands are ignored from the Dockerfile.
How can a web docker app simply get permission to write on a host directory ?
So you are building an image, setting chmods, and it's all cool.
But then you run the container with -v option, which means /data will be replaced with mounted volume. At this time all files and permissions from built image are ignored. You can check this by running container without -v option. The solution is to create entrypoint script (with ENTRYPOINT or CMD command in Dockerfile) which will first fix permissions and then run original command for your image.