简体   繁体   English

Docker卷不保留数据

[英]Docker volume does not persist data

Here is my docker file: 这是我的docker文件:

FROM ubuntu:14.04

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list

RUN apt-get update && apt-get -y -q install python-software-properties software-properties-common \
    && apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3

USER postgres
RUN /etc/init.d/postgresql start \
    && psql --command "CREATE USER pguser WITH SUPERUSER PASSWORD 'pguser';" \
    && createdb -O pguser pgdb
USER root
RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
EXPOSE 5432

RUN mkdir -p /var/run/postgresql && chown -R postgres /var/run/postgresql
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
USER postgres

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

Here is what I did... 这是我做的...

  1. I build the docker image: 我构建了docker镜像:

     docker build --rm=true -t my_image/postgresql:9.3 
  2. Then, I create a new directory called data in my current directory and ran the following command: 然后,我在当前目录中创建一个名为data的新目录,并运行以下命令:

     docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3 
  3. I open another terminal and enter the postgres shell by running: 我打开另一个终端并通过运行进入postgres shell:

     psql -h my_docker_ip -p 5432 -U pguser -W pgdb 

    and I create a table: 然后创建一个表:

     pgdb=# create table test (test_id bigserial primary key); 
  4. I verify the table exist using \\dt and exit the postgres shell 我使用\\dt验证表是否存在并退出postgres shell

  5. I terminate the docker process and rerun the following: 我终止docker进程并重新运行以下命令:

     docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3 
  6. I enter the posgrest shell again and run \\dt 我再次进入posgrest shell并运行\\dt

  7. I notice 我注意到
    • there are no tables. 没有桌子。
    • in the data directory there are no files. data目录中没有文件。

I must be doing something wrong since I am assuming that the table I created will persist. 我肯定做错了,因为我假设我创建的表将持久存在。 Can someone point out my mistake? 有人可以指出我的错误吗?

Based on your comment: 根据您的评论:

the data persisted, but I still can't find the persist data in my host ./data directory 数据已持久,但是我仍然无法在主机./data目录中找到持久数据

and running this command: 并运行以下命令:

docker run -i -t -v="data:/data" -p 5432:5432 my_image/postgresql:9.3

You appear to be confusing a named volume and a host volume. 您似乎混淆了命名卷和主机卷。 The named volume is used when you give the volume a name without a path, like data . 当您给卷命名时没有路径,例如data ,则使用命名卷。 The named volume stores the data using the docker driver (typically local) under a given name that you can reuse. 命名卷使用泊坞窗驱动程序(通常是本地驱动器)以可重用的给定名称存储数据。 It has the advantage of being listed in docker volume ls , and being initialized to the content of the image at the mounted location. 它具有在docker volume ls列出并在安装位置初始化为映像内容的优点。

If you include a full path, like /home/username/data that would mount the directory from the docker host instead of using the named volume. 如果包括完整路径,例如/home/username/data ,它将从Docker主机而不是使用命名卷挂载目录。 The biggest disadvantage is that you don't get the directory initialized with the contents from the image, and you will likely encounter permission issues where the uid of the container process won't match the uid you use on your host. 最大的缺点是您没有使用映像中的内容初始化目录,并且可能会遇到权限问题,其中容器进程的uid与您在主机上使用的uid不匹配。

For more details, see https://docs.docker.com/engine/tutorials/dockervolumes/ 有关更多详细信息,请参阅https://docs.docker.com/engine/tutorials/dockervolumes/

There is something that confused me and for me was not very clear in the official documentation. 有一些让我感到困惑的事情,对我而言,官方文档中并不清楚。

To my knowledge, persistent volumes can be created in three ways. 据我所知,可以通过三种方式创建持久卷。

  • At container invocation time including full path ( -v ~/database:/data ): makes an external folder from the host available inside the docker container. 在包含完整路径( -v ~/database:/data )的容器调用时 :使主机的外部文件夹在docker容器内可用。 Both can modify it. 两者都可以修改它。
  • At container invocation time using a volume name ( -v datamysql:/data ): makes a volume that is persistent available inside the container. 在容器调用时,使用卷名( -v datamysql:/data ):在容器内部使持久卷可用。 It is created it if it did not exist. 如果它不存在,则会创建它。 You can list them by name with docker volume ls . 您可以使用docker volume ls按名称列出它们。 Internally, it will be stored in a place such as /var/lib/docker/volumes/ae4445f7c9317a22fe84726fb894c47754f38a7fd150c00fd877024889968750/_data . 在内部,它将存储在/var/lib/docker/volumes/ae4445f7c9317a22fe84726fb894c47754f38a7fd150c00fd877024889968750/_data
  • At container build time ( VOLUME ["/database/data"] in Dockerfile). 在容器构建时 (Dockerfile中的VOLUME ["/database/data"] )。 Every invocation of docker run will create a new volume that will persist even if you delete the container. 每次docker run调用都会创建一个新卷,即使您删除容器,该卷也将保留。 This can be confusing becausee subsequent invocations will result in different volumes being created that will not be reused. 这可能会造成混乱,因为后续的调用将导致创建不同的卷,而这些卷将无法重用。

You can list both named (second case) and unnamed (third case) volumes with 您可以使用以下命令列出已命名(第二种情况)卷和未命名(第三种情况)卷

$ docker volume ls                                                             
DRIVER              VOLUME NAME                                                             
local               064593b3e65977097d4d0c8402a6c633f1af69be2937bf118678ab8f97ee9a7e               
local               4753ad0437d13e54c76d9c34a30a1843396a1866a0cf9237d500fdcca0d78c5f           
local               8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415               
local               db48eefe8f189b36107ca9c4eebb792690590ab0ba055e7e4e2c9adfd1765b7e                    
local               datamysql

You can see the exact location of a container's volume by using docker inspect mycontainer 您可以使用docker inspect mycontainer容器的确切位置

{
                "Type": "volume",
                "Name": "8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415",
                "Source": "/media/USBdrive/docker/volumes/8d7a35354f666b2e8a26866a35bbae36bb9601701d4c6b505ab8ce6629f69415/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },

It might be handy to remove unused volumes (for the third case, specially). 删除未使用的卷可能很方便(特别是对于第三种情况)。

$ docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
4753ad0437d13e54c76d9c34a30a1843396a1866a0cf9237d500fdcca0d78c5f

Total reclaimed space: 205MB

Because you used the VOLUME directive in your Dockerfile, you are in the third case. 因为您在Dockerfile中使用了VOLUME指令,所以处于第三种情况。 Inspect your container to look for the file, and specify the volume from the command line if you want repeated sessions to persist data. 检查您的容器以查找文件,如果要重复的会话来保留数据,请从命令行指定卷。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM