我的更改在新Docker容器中丢失

nzkunb0c  于 2023-02-18  发布在  Docker
关注(0)|答案(2)|浏览(246)

重现步骤:
1.下载并运行postgres:9.6.24

docker run --name my_container --restart=always -d -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=pgmypass postgres:9.6.24

结果如下:

CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                      NAMES
879883bfc84a   postgres:9.6.24   "docker-entrypoint.s…"   26 seconds ago   Up 25 seconds   127.0.0.1:5432->5432/tcp   my_container

好的。
1.打开容器/var/lib/postgresql/data/pg_hba.conf中的文件

docker exec -it my_container bash
   root@879883bfc84a:/# cat /var/lib/postgresql/data/pg_hba.conf

   IPv4 local connections:
   host    all             all             127.0.0.1/32            trust

1.用我的文件替换容器内的文件/var/lib/postgresql/data/pg_hba.conf。将我的文件从主机复制并覆盖到容器:

tar --overwrite -c pg_hba.conf | docker exec -i my_container /bin/tar -C /var/lib/postgresql/data/ -x

1.请确保文件已被修改。进入容器并打开更改的文件

docker exec -it my_container bash
       root@879883bfc84a:/# cat /var/lib/postgresql/data/pg_hba.conf
       IPv4 local connections:
       host    all             all            0.0.0.0/0                trust

正如您所看到的文件内容已更改。
1.从容器创建新映像

docker commit my_container

参见结果:

docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
<none>       <none>    ee57ad4bc6b4   3 seconds ago   200MB 
postgres     9.6.24    027ccf656dc1   12 months ago   200MB

现在标记我的新图像

docker tag ee57ad4bc6b4 my_new_image:1.0.0

参见结果:

docker images
REPOSITORY         TAG       IMAGE ID       CREATED              SIZE
my_new_image       1.0.0     ee57ad4bc6b4   About a minute ago   200MB
postgres           9.6.24    027ccf656dc1   12 months ago        200MB

好的。
1.停止并删除旧的容器:

docker stop my_continer
docker rm my_container

参见结果:

docker ps -a
   CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

如你所见,不要离开任何容器。好的。
1.从新映像创建新容器

docker run --name my_new_container_test --restart=always -d -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=pg1210 my_new_image:1.0.0

参见结果:

docker ps

CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS                      NAMES
3a965dbbd991   my_new_image:1.0.0   "docker-entrypoint.s…"   7 seconds ago   Up 6 seconds   127.0.0.1:5432->5432/tcp   my_new_container

1.打开容器/var/lib/postgresql/data/pg_hba.conf中的文件

docker exec -it my_new_container bash
   root@879883bfc84a:/# cat /var/lib/postgresql/data/pg_hba.conf

   IPv4 local connections:
   host    all             all             127.0.0.1/32            trust

正如你所看到的,我的文件中的更改丢失了。文件的内容是原始的。不是我的更改。
P.S.此问题仅与文件pg_hba. config有关。例如,如果我在容器中创建文件夹和文件:/Downaloads/myfile.txt,则此文件不会在我的容器"my_new_container"中丢失。

zvms9eto

zvms9eto1#

一般来说,使用docker exec编辑container中的文件实际上会导致您丢失工作。您提到了docker commit,但这几乎从来都不是最佳实践。(如果这是成功的,但随后您发现PostgreSQL 9.6.24确实有一些严重的bug,您必须升级,您能重新创建一些映像吗?)
postgres映像的情况下,/var/lib/postgresql/data中的文件总是存储在Docker卷或挂载点中。在您的情况下,您没有使用docker run -v选项,但映像被配置为在该目录中创建匿名卷。该卷不包括在docker commit中,这就是为什么您在重建的容器中看不到它。(另请参见docker postgres with initial data is not persisted over commits
要编辑配置文件,最简单的方法是将数据存储在主机系统上。创建一个目录来保存数据,然后从映像中提取配置文件。(由于数据目录是由映像的启动脚本创建的,因此需要稍长的路径才能将其提取出来。)

mkdir pgdata
docker run -d --name pgtmp postgres:9.6.24
docker cp pgtmp:/var/lib/postgresql/data/pg_hba.conf ./pgdata
docker stop pgtmp
docker rm pgtmp

$EDITOR pgdata/pg_hba.conf

现在,当您运行容器时,将此数据目录作为绑定挂载提供,这将注入配置文件,但也会导致数据库数据在容器退出时保持不变。

docker run -v "$PWD/pgdata:/var/lib/postgresql/data" -u $(id -u) ... postgres:9.6.24

注意这个序列根本不使用docker exec或“go inside”容器,并且您没有创建没有相应源代码的映像。所有操作都是通过主机的命令运行的。如果您确实需要重置数据库数据,在这个设置中,它只是文件,您可以使用rm -rf pgdata,可能会保存修改后的配置文件。
(If我正确地阅读了这个配置更改,您正在尝试全局禁用密码,而允许对所有入站连接使用trust身份验证。这通常不是一个好主意,尤其是因为用户名/密码身份验证在我遇到的每个数据库中都是标准的。您可能仍然希望卷持久化数据,但我可能不会对pg_hba.conf进行此更改。

6uxekuva

6uxekuva2#

Docker Container是一个只读实体,这意味着如果您要在容器中创建一个文件,删除它并重新创建它(容器),该文件不应该在那里。
你要做的只有两件事
1.将容器Map到本地目录(卷)
1.基于postgres映像创建一个docker文件,并在一个脚本中生成这些修改,您的docker文件可以读取这些修改。
docker volume usages
停靠文件参考

相关问题