我正在尝试/调试/学习/破解Docker。我目前正在编写Docker代码,以为我的应用程序创建快照测试环境。
通过snapshotted
是指每次重新启动时都会有意重置数据库,以便可以在特定时间使用旧数据。在我的情况下,特有的是我想在构建时而不是在启动时填充Postgresql数据库。 Postgresql映像已准备就绪,可以在容器启动时使用sql脚本填充数据库,但这需要几个小时。
我的应用程序是由运行WAR的Tomcat 8.5服务器和Postgresql数据库组成的,这是我现在问题的重点。在编写完整代码时,我正在创建一个Gist。
我有followed a tutorial关于如何构建具有完整数据库的Postgres Docker映像的知识,而不是让Postgres在启动时自行填充。这是因为我有一个million record database,并且只有sysop给我的一个.sql.gz
转储。
所以Dockerfile的相关部分是
WORKDIR /opt/setup/
COPY db-setup.sh /opt/setup/
COPY db-pack.sh /opt/setup/
COPY db-run.sh /opt/setup/
RUN ./db-setup.sh
RUN ./db-pack.sh
#VOLUME $PGDATA (Note it is commented out, now)
EXPOSE 5432
db-setup.sh
在映像构建中运行,并从data-scripts.d
中选取文件。当然,我不允许共享转储的内容,但是它是一个普通的.sql.gz,其中包含大量OID
s,需要大量时间来还原。 Gist中显示的db-setup.sh
来自于本教程和原始Postgres图像,因此它可以正确处理压缩(本教程仅使用纯SQL)
构建图像时,加载数据需要花费大量时间,这正是我想要的
2019-08-07 07:57:04.149 UTC [49] LOG: database system was shut down at 2019-08-07 07:57:03 UTC
2019-08-07 07:57:04.231 UTC [48] LOG: database system is ready to accept connections
done
server started
./db-setup.sh: running methodinv_pcp3.sql.gz
2019-08-07 08:49:52.052 UTC [117] ERROR: canceling autovacuum task
2019-08-07 08:49:52.052 UTC [117] CONTEXT: automatic analyze of table "postgres.public.ftt_interactive_data_492"
2019-08-07 08:49:59.086 UTC [118] ERROR: canceling autovacuum task
2019-08-07 08:49:59.086 UTC [118] CONTEXT: automatic analyze of table "postgres.public.ftt_oper_492"
2019-08-07 08:50:34.086 UTC [118] ERROR: canceling autovacuum task
2019-08-07 08:50:34.086 UTC [118] CONTEXT: automatic analyze of table "postgres.public.ftt_validation_492"
2019-08-07 08:51:11.889 UTC [119] ERROR: canceling autovacuum task
2019-08-07 08:51:11.889 UTC [119] CONTEXT: automatic analyze of table "postgres.public.ftt_oper_492"
2019-08-07 08:54:21.131 UTC [123] ERROR: canceling autovacuum task
2019-08-07 08:54:21.131 UTC [123] CONTEXT: automatic analyze of table "postgres.public.ftt_oper_492"
waiting for server to shut down...2019-08-07 08:54:28.652 UTC [48] LOG: received fast shutdown request
.2019-08-07 08:54:28.797 UTC [48] LOG: aborting any active transactions
2019-08-07 08:54:28.799 UTC [48] LOG: worker process: logical replication launcher (PID 55) exited with exit code 1
2019-08-07 08:54:28.800 UTC [50] LOG: shutting down
..2019-08-07 08:54:31.407 UTC [48] LOG: database system is shut down
done
当我使用docker run
运行映像时,启动失败,因为它找不到Postgres配置
D:\IdeaProjects\pcp\ftt-containers\ftt-db-method>docker run -p 5432:5432 -l ftt-db-method ftt-db-method:latest
Restoring /var/lib/postgresql/data ...
Done.
Launching command: postgres ...
postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory
最初,我的Dockerfile公开了一个VOLUME
,现在已将其注释掉。当我声明一个卷(这并不是我真正想要的,不是我刚接触Docker并有第一次机会复制并粘贴)时,以及在我注释掉该卷时,都会发生以上输出。
已满载我正在尝试的大量数据的Postgres的Docker映像出了什么问题?
如何在容器已重启的情况下有效地使用已经无法的完整数据库启动Postgres?通过bash
-进入容器,我发现在构建期间创建的数据转储为10K,因此基本上为空。
这还不能解决我的问题,但是可以回答为什么Postgres无法找到其喜爱的数据目录
编辑2
我能够猛扑到一个临时容器中,尤其是在还原数据库和打包数据库之间。
基本上Dockerfile可以
RUN ./db-setup.sh
哪个执行sql的还原
echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}" > /dev/null 2>&1 ; echo ;;
输出被保存到一个临时容器中。 现在Dockerfile了
RUN ./db-pack.sh
将tar
的{{1}}插入/var/lib/postgresql/data
中。我有
/zdata
因此,我将2019-08-07 16:43:51.532 UTC [42] LOG: received fast shutdown request
waiting for server to shut down....2019-08-07 16:43:51.676 UTC [42] LOG: aborting any active transactions
2019-08-07 16:43:51.679 UTC [42] LOG: worker process: logical replication launcher (PID 49) exited with exit code 1
2019-08-07 16:43:51.681 UTC [44] LOG: shutting down
...2019-08-07 16:43:54.952 UTC [42] LOG: database system is shut down
done
server stopped
Removing intermediate container 8dbe2a4e776a
---> 263896b905ce
Step 15/19 : RUN ./db-pack.sh
---> Running in 56132ecb90cc
Packing data folder: /var/lib/postgresql/data
Pack & clean finished successfully.
Removing intermediate container 56132ecb90cc
---> 1a7f8d68e8df
Step 16/19 : VOLUME $PGDATA
---> Running in 10d222beed81
Removing intermediate container 10d222beed81
---> e1a9355882d1
(如果在您的PC上进行复制,则为YHMV)标记为新图像,然后对其执行bash。数据目录为空,脚本将不会打包任何内容
263896b905ce
答案 0 :(得分:0)
固定
根据https://stackoverflow.com/a/52762779/471213
“为什么VOLUME不起作用?”在Dockerfile中定义VOLUME时,只能定义目标,而不能定义卷的源。在构建期间,您将仅从中获得一个匿名卷。该匿名卷将在每个RUN命令处挂载,并预先填充映像的内容,然后在RUN命令末尾丢弃。 仅保存对容器所做的更改,而不更改对体积的更改。
所以我基本上必须同时运行两个RUN
RUN ./db-setup.sh && ./db-pack.sh
#RUN ./db-pack.sh