当前位置: 首页 > 知识库问答 >
问题:

在Docker中启动并填充Postgres容器

壤驷康裕
2023-03-14

我有一个Docker容器,其中包含我的Postgres数据库。它使用官方的Postgres映像,其中有一个CMD条目,可以在主线程上启动服务器。

我想通过运行RUN psql–U postgres postgres来填充数据

我不明白这怎么可能和码头工人在一起。如果我把RUN命令放在CMD之后,它当然永远不会到达,因为Docker已经完成了Dockerfile的读取。但是如果我把它放在CMD之前,它甚至会在psql作为进程存在之前运行。

如何在Docker中预填充Postgres数据库?


共有3个答案

谷梁子濯
2023-03-14

或者,您可以将一个卷挂载到 /docker-entrypoint-initdb.d/其中包含所有DDL脚本。您可以放入*. sh、*. sql或*.sql.gz文件,它将负责在启动时执行这些文件。

e、 g.(假设您的脚本位于/tmp/my_脚本中)

docker run -v /tmp/my_scripts:/docker-entrypoint-initdb.d postgres
段干华皓
2023-03-14

对于那些希望在第一次运行时使用数百万条记录初始化PostgreSQL数据库的用户。

您可以进行简单的sql转储,并将dump.sqlhtml" target="_blank">文件复制到/docker-entrypoint-initdb. d/中。问题是速度。我的dump.sql脚本大约是17MB(小型DB-10表,其中只有一个100k行),初始化需要一分钟(!)。这对于本地开发/单元测试等是不可接受的。

解决方案是创建一个二进制PostgreSQL转储,并使用shell脚本初始化支持。然后相同的DB在大约500ms而不是1分钟内初始化。

1.直接从容器或本地数据库中创建名为“my-db”的数据库的dump.pgdata二进制转储

pg_dump -U postgres --format custom my-db > "dump.pgdata"

或从运行容器(postgres容器)的主机

docker exec postgres-container pg_dump -U postgres --format custom my-db > "dump.pgdata"

2.使用给定的转储和初始化脚本创建Docker映像

$ tree
.
├── Dockerfile
└── docker-entrypoint-initdb.d
    ├── 01-restore.sh
    ├── 02-small-updates.sql
    └── dump.pgdata
$ cat Dockerfile
FROM postgres:11

COPY ./docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
$ cat docker-entrypoint-initdb.d/01-restore.sh
#!/bin/bash

file="/docker-entrypoint-initdb.d/dump.pgdata"
dbname=my-db

echo "Restoring DB using $file"
pg_restore -U postgres --dbname=$dbname --verbose --single-transaction < "$file" || exit 1
$ cat docker-entrypoint-initdb.d/02-small-updates.sql
-- some updates on your DB, for example for next application version
-- this file will be executed on DB during next release
UPDATE ... ;

3.建立一个图像并运行它

$ docker build -t db-test-img .
$ docker run -it --rm --name db-test db-test-img
罗光华
2023-03-14

经过多次斗争,我找到了解决办法;-)

对我来说,在这里发布的一条评论非常有用:https://registry.hub.docker.com/_/postgres/来自“公正”

反正我是这样做的:

# Dockerfile
FROM postgres:9.4

RUN mkdir -p /tmp/psql_data/

COPY db/structure.sql /tmp/psql_data/
COPY scripts/init_docker_postgres.sh /docker-entrypoint-initdb.d/

db/structure。sql是一个sql转储,用于初始化第一个表空间。

然后,init\u docker\u postgres。sh

#!/bin/bash

# this script is run when the docker container is built
# it imports the base database structure and create the database for the tests

DATABASE_NAME="db_name"
DB_DUMP_LOCATION="/tmp/psql_data/structure.sql"

echo "*** CREATING DATABASE ***"

# create default database
gosu postgres postgres --single <<EOSQL
  CREATE DATABASE "$DATABASE_NAME";
  GRANT ALL PRIVILEGES ON DATABASE "$DATABASE_NAME" TO postgres;
EOSQL

# clean sql_dump - because I want to have a one-line command

# remove indentation
sed "s/^[ \t]*//" -i "$DB_DUMP_LOCATION"

# remove comments
sed '/^--/ d' -i "$DB_DUMP_LOCATION"

# remove new lines
sed ':a;N;$!ba;s/\n/ /g' -i "$DB_DUMP_LOCATION"

# remove other spaces
sed 's/  */ /g' -i "$DB_DUMP_LOCATION"

# remove firsts line spaces
sed 's/^ *//' -i "$DB_DUMP_LOCATION"

# append new line at the end (suggested by @Nicola Ferraro)
sed -e '$a\' -i "$DB_DUMP_LOCATION"

# import sql_dump
gosu postgres postgres --single "$DATABASE_NAME" < "$DB_DUMP_LOCATION";


echo "*** DATABASE CREATED! ***"

因此,最后:

# no postgres is running
[myserver]# psql -h 127.0.0.1 -U postgres
psql: could not connect to server: Connection refused
    Is the server running on host "127.0.0.1" and accepting
    TCP/IP connections on port 5432?

[myserver]# docker build -t custom_psql .
[myserver]# docker run -d --name custom_psql_running -p 5432:5432 custom_psql

[myserver]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              PORTS                    NAMES
ce4212697372        custom_psql:latest   "/docker-entrypoint.   9 minutes ago       Up 9 minutes        0.0.0.0:5432->5432/tcp   custom_psql_running

[myserver]# psql -h 127.0.0.1 -U postgres
psql (9.2.10, server 9.4.1)
WARNING: psql version 9.2, server version 9.4.
         Some psql features might not work.
Type "help" for help.

postgres=# 

# postgres is now initialized with the dump

希望有帮助!

 类似资料:
  • 问题内容: 我想在Centos7的Docker容器中运行Jenkins。我看到了Jenkins的官方文档:首先,从Docker存储库中提取官方的jenkins映像。 接下来,使用该映像运行一个容器,并将数据目录从该容器映射到主机;例如,在下面的示例中,容器中的/ var / jenkins_home从主机上的当前路径映射到jenkins /目录。Jenkins 8080端口也以49001的身份向主

  • 问题内容: 我使用以下命令创建了容器: 以下是命令: 真的没有太多要说的,我希望容器能启动并保持正常运行。这是日志: 问题答案: 您正在尝试运行,它是需要tty 才能运行的交互式外壳。使用,在“分离”模式下运行此命令实际上没有任何意义,但是您可以通过添加到命令行来做到这一点,以确保容器具有与其关联的有效tty并保持连接状态: 在启动分离的容器时,您通常会运行某种长期存在的非交互式进程(例如,或We

  • 问题内容: 要为Ubuntu映像启动交互式shell,我们可以运行: 但是,对于Alpine Docker映像运行此命令时,将得到以下结果: 在Alpine基本容器中启动交互式Shell的命令是什么? 问题答案: 上面使用的选项: 是BusyBox提供的Ash(Almquist Shell)。 退出时自动移除容器() 交互模式(即使未连接也保持STDIN打开) 分配伪TTY

  • 我正在使用Debezium Postgres连接器。我在Postgres中有两个表,分别命名为'publications'和'comments'。根据标准示例,kafka和zookeeper运行在docker容器中。postgres正在本地运行。在使用debezium postgres connect之后,我有以下主题: __consumer_offsets dbserver1.public.co

  • 然后 但是当我执行命令时,我出现了这个错误知道我的数据库已有表。我做错了吗?