我是Postgres的新手。
我更新了我使用的Dockerfile并成功安装了Postgresql。 (我的图像运行Ubuntu 16.04,我正在使用Postgres 9.6。)
一切正常,直到我尝试将数据库移动到Volume
docker-compose
(这是在使用cp -R /var/lib/postgresql /somevolume/
制作容器文件夹的副本之后。)
问题是Postgres一直在崩溃,正如supervisord所见:
2017-07-26 18:55:38,346 INFO exited: postgresql (exit status 1; not expected)
2017-07-26 18:55:39,355 INFO spawned: 'postgresql' with pid 195
2017-07-26 18:55:40,430 INFO success: postgresql entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-07-26 18:55:40,763 INFO exited: postgresql (exit status 1; not expected)
2017-07-26 18:55:41,767 INFO spawned: 'postgresql' with pid 197
2017-07-26 18:55:42,841 INFO success: postgresql entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2017-07-26 18:55:43,179 INFO exited: postgresql (exit status 1; not expected)
(and so on…)
我不清楚发生了什么,因为/var/log/postgresql
仍然是空的。
我怀疑它与用户有关。如果我将容器内的数据文件夹和我制作的副本与卷进行比较,唯一的区别是原件归postgres
所有,而副本归root
所有。
我尝试在副本上运行chown -R postgres:postgres
。该操作已成功执行,但postmaster.pid
仍由root
拥有,我认为这将是问题所在。
postmaster.id
拥有postgres
?root
来运行postgres吗?任何暗示欢迎。
编辑:指向the Dockerfile和docker-compose.xml的链接。
答案 0 :(得分:5)
我会回答我自己的问题:
让事情变得更复杂的是我没有收到任何具体的错误信息。
要改变这一点,我在supervisord中禁用了[program:postgresql]
部分,而是从命令行手动启动了postgres(感谢Miguel Marques通过他的评论让我走上了正确的轨道。)
然后我终于得到了一些有用的错误消息:
2017-08-02 08:27:09.134 UTC [37] LOG: could not open temporary statistics file "/var/run/postgresql/9.6-main.pg_stat_tmp/global.tmp": No such file or directory
我修复了上面的错误,最后将它们添加到我的Dockerfile
:
mkdir -p /var/run/postgresql/9.6-main.pg_stat_tmp
chown postgres.postgres /var/run/postgresql/9.6-main.pg_stat_tmp -R
(感谢this guy提供修复。)
为了使数据永久化,我还必须这样做,因为postgres可以访问卷:
mkdir -p /var/lib/postgresql/9.6/main
chmod 700 /var/lib/postgresql/9.6/main
我还使用initdb
来初始化数据目录。谨防!这将删除该文件夹中的所有数据。像这样:
rm -R /var/lib/postgresql/9.6/main/*
ls /var/lib/postgresql/9.6/main/
/usr/lib/postgresql/9.6/bin/initdb -D /var/lib/postgresql/9.6/main
在上述之后,我终于可以正确运行postgres了。我使用此命令运行它并从命令行进行测试:
su postgres
/usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf # as per the Docker docs
为了测试,我保持运行,然后,从另一个提示,检查一切运行正常:
su postgres
psql
CREATE TABLE cities ( name varchar(80), location point );
INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
select * from cities; # repeat this command after restarting the container to check that the data does persist
...确保重新启动容器并再次测试以检查数据是否仍然存在。
然后最终恢复了supervisord中的[program:postgresql]
部分,重建了图像并重新启动了容器,确保一切正常(特别是supervisord:tail /var/log/supervisor/supervisord.log
),它确实如此。
(我在supervisord.conf中使用的命令也是/usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf
,根据this Docker article和其他postgres + supervisord示例。其他选项可能是pg_ctl
或一个init.d
脚本,但我不清楚为什么/何时会使用这些脚本。)
我花了很多时间在这上面。希望详细的答案可以帮助有人下线。
P.S。:我最终制作了一个我的问题的最小例子。如果这可以帮助任何人,那么他们就是:Dockerfile,supervisord.conf和docker-compose.yml。
答案 1 :(得分:3)
我不知道这是否是实现相同结果的另一种方式(我也是Docker和Postgres的新手),但您是否尝试过Postgres(https://hub.docker.com/_/postgres/)的官方存储库图像?
我从容器中获取数据,将环境变量PGDATA设置为'/ var / lib / postgresql / data / pgdata'并将其绑定到运行命令的外部卷:
<NSProgress: 0x600000520280> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 41605
<NSProgress: 0x600000527580> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 29438
<NSProgress: 0x60000052b5e0> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 29438
<NSProgress: 0x60000052a5a0> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 41605
<NSProgress: 0x600000527800> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 41605
<NSProgress: 0x60000052b7c0> : Parent: 0x0 / Fraction completed: 0.0026 / Completed: 108 of 41713
<NSProgress: 0x60000052aaa0> : Parent: 0x0 / Fraction completed: 0.0037 / Completed: 108 of 29546
<NSProgress: 0x60000052b7c0> : Parent: 0x0 / Fraction completed: 0.0037 / Completed: 108 of 29546
<NSProgress: 0x60000052ab40> : Parent: 0x0 / Fraction completed: 0.0026 / Completed: 108 of 41713
<NSProgress: 0x60000052ab40> : Parent: 0x0 / Fraction completed: 0.0026 / Completed: 108 of 41713
<NSProgress: 0x60000052c1c0> : Parent: 0x0 / Fraction completed: 0.1990 / Completed: 8300 of 41713
<NSProgress: 0x60000052c1c0> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
<NSProgress: 0x60000052c1c0> : Parent: 0x0 / Fraction completed: 0.1990 / Completed: 8300 of 41713
<NSProgress: 0x6080001381a0> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
<NSProgress: 0x60000052c6c0> : Parent: 0x0 / Fraction completed: 0.2809 / Completed: 8300 of 29546
<NSProgress: 0x60000052c6c0> : Parent: 0x0 / Fraction completed: 0.1990 / Completed: 8300 of 41713
<NSProgress: 0x60000052c760> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
<NSProgress: 0x608000139000> : Parent: 0x0 / Fraction completed: 0.2809 / Completed: 8300 of 29546
<NSProgress: 0x608000136ee0> : Parent: 0x0 / Fraction completed: 0.2809 / Completed: 8300 of 29546
<NSProgress: 0x60000052b180> : Parent: 0x0 / Fraction completed: 0.2809 / Completed: 8300 of 29546
<NSProgress: 0x60000052c120> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
<NSProgress: 0x608000139280> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
<NSProgress: 0x60000052bb80> : Parent: 0x0 / Fraction completed: 1.0000 / Completed: 41713 of 41713
当卷为空时,所有文件都由映像启动脚本创建,如果它们已经存在,则数据库开始使用它。
答案 2 :(得分:1)
根据过去的经验,我可以看到可能存在的问题。我不能说这是否会有所帮助,但值得一试。 我会将此作为评论添加,但我不能,因为我的代表不够高。
我在您的Dockerfile中如何构建语句时遇到了一些问题。您已多次安装各种内容,并且还通过代码偶尔更新。在我自己的文件中,我注意到由于层次不同,这会导致我的服务和安装有些随机行为。
这似乎无法直接解决您的问题,但是最佳实践中概述的清理文件已经解决了我过去的许多Dockerfile问题。
发现此类问题的第一个地方之一就是从best practices for RUN开始。这帮助我解决过去棘手的问题,我希望它能解决或者至少让它变得容易。
特别注意这一部分:
构建映像后,所有层都在Docker缓存中。假设您稍后通过添加额外的包来修改apt-get install:
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y curl nginx
Docker将初始和修改后的指令视为相同,并重用之前的缓存 脚步。因此,不执行apt-get更新,因为 build使用缓存版本。因为apt-get更新没有运行, 你的构建可能会得到一个过时的curl版本 nginx包。
阅读完本文后,我将首先整合所有依赖项。