重现步骤:
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"中丢失。
2条答案
按热度按时间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。要编辑配置文件,最简单的方法是将数据存储在主机系统上。创建一个目录来保存数据,然后从映像中提取配置文件。(由于数据目录是由映像的启动脚本创建的,因此需要稍长的路径才能将其提取出来。)
现在,当您运行容器时,将此数据目录作为绑定挂载提供,这将注入配置文件,但也会导致数据库数据在容器退出时保持不变。
注意这个序列根本不使用
docker exec
或“go inside”容器,并且您没有创建没有相应源代码的映像。所有操作都是通过主机的命令运行的。如果您确实需要重置数据库数据,在这个设置中,它只是文件,您可以使用rm -rf pgdata
,可能会保存修改后的配置文件。(If我正确地阅读了这个配置更改,您正在尝试全局禁用密码,而允许对所有入站连接使用
trust
身份验证。这通常不是一个好主意,尤其是因为用户名/密码身份验证在我遇到的每个数据库中都是标准的。您可能仍然希望卷持久化数据,但我可能不会对pg_hba.conf
进行此更改。6uxekuva2#
Docker Container是一个只读实体,这意味着如果您要在容器中创建一个文件,删除它并重新创建它(容器),该文件不应该在那里。
你要做的只有两件事
1.将容器Map到本地目录(卷)
1.基于postgres映像创建一个docker文件,并在一个脚本中生成这些修改,您的docker文件可以读取这些修改。
docker volume usages
停靠文件参考