问题
I am just starting with Docker, please pardon me if my question is too silly for you.
I see some images, like nginx
, does not have any VOLUME
defined whereas some images like mysql
has VOLUME
defined in their Dockerfile.
How the data or files are managed when there is no volume defined, and what would be their working directory?
回答1:
A preferred pattern for many applications you can run in a container is to store no state at all locally. If I have a Web application, and perhaps it takes a configuration file as input, but it stores all of its data in an external database, I need no local storage. In turn, that means that I can run several copies of it for redundancy or to support larger scales, and I don't need to worry about preserving data if I need to replace a container. If my containers are in fact stateless, then I have no need for a VOLUME
(or to attach volumes to my container at runtime).
Even if your container does have local state, you probably don't want VOLUME
. What VOLUME
actually means is, when a container runs, if nothing else is mounted on the named filesystem path, create an anonymous volume and mount it there (letting Docker populate it from image content). In practice, this means:
- You can use
docker run -v
or Docker Composevolumes:
to mount a directory on any container filesystem path, regardless of whether or not it's declared as aVOLUME
. - If something is declared as a
VOLUME
, laterRUN
instructions can't change that directory tree. - If something is declared as a
VOLUME
, you can never create a derived image that has different contents at that location (for example, you can't create an image derivedFROM postgresql
with preloaded data).
There's no particular point to declaring VOLUME /tmp
(as seems to be common in Java Dockerfiles) or for declaring VOLUME
over parts of your application code.
VOLUME
declarations are unrelated to an image's WORKDIR
.
回答2:
As illustrated in "Understanding “VOLUME” instruction in DockerFile", a VOLUME in Dockerfile creates a mount point within the container.
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
This Dockerfile results in an image that causes docker run to create a new mount point at
/myvol
and copy the greeting file into the newly created volume.
This was originally done for different containers to mount and access data from other containers.
See docker run --volumes-from
This is different from data persistence, where you want runtime session data to persist on disk.
For that, see "Manage data in Docker", where you can, at runtime, mount docker volumes, or Host folders (bind mounts), or tmpfs (for writing a large volume of non-persistent state data in the host system’s memory only, for performance, but without persistence)
NGiNX by default won't share data with other containers, so does not declare VOLUME
in its Dockerfile.
How about NGiNX ? I see static files are at
/usr/share/nginx/html
but when I cd to this location from host cli it says directory not found, but when I cd from bash mode when executing container in interactive mode this path is displayed
It is meant to receive data from host through bind mount:
docker run --name mynginx \
-v /var/www:/usr/share/nginx/html:ro \
-v /var/nginx/conf:/etc/nginx:ro
-P -d nginx
Those data are "ro
" (read-only) within the container.
/usr/share/nginx/html
is a path from within the container, which is why, if you cd
to it on the host, you would not find it.
回答3:
Docker has the concept of volumes, which are persistent, meaning if the docker container for any reason has to restart, the same volume is attached to the new container and the data is not lost.
For that reason is that a MySQL container has a data volume attached to it. Which is attached in the path that the container stores the MySQL data.
You can attach a volume in any path from your localhost to any path to the container.
来源:https://stackoverflow.com/questions/61759981/why-do-some-docker-images-have-no-volume-defined