[英]docker-compose postgres restart after running scripts in docker-entrypoint-initdb.d
I have a simple Docker Compose file to initialize a Postgres DB Instance:我有一个简单的 Docker 编写文件来初始化 Postgres 数据库实例:
version: '3.8'
services:
my-database:
container_name: my-database
image: library/postgres:13.1
volumes:
- ./db/init-my-database.sql:/docker-entrypoint-initdb.d/init-db-01.sql
environment:
- POSTGRES_DB=my-database
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
ports:
- 10040:5432
restart: always
networks:
- app-network
And my script init-my-database.sql looks like this:我的脚本init-my-database.sql看起来像这样:
DROP DATABASE IF EXISTS myschema;
CREATE DATABASE myschema;
-- Make sure we're using our `myschema` database
\c myschema;
CREATE SEQUENCE IF NOT EXISTS recipient_seq
START WITH 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE IF NOT EXISTS recipient
(
id BIGINT NOT NULL,
recipient_id VARCHAR(255) NOT NULL,
first_name VARCHAR(255) NOT NULL,
middle_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
CONSTRAINT recipient_pk PRIMARY KEY (id)
);
When I tail the Docker logs I do see that the initialization script is being called.当我跟踪 Docker 日志时,我确实看到正在调用初始化脚本。 However, towards the end the database is shutdown and restarted --> " received fast shutdown request "然而,到最后数据库被关闭并重新启动-->“收到快速关闭请求”
Why is the database restarted at the end?为什么最后会重启数据库? As the database and table created in the script is not available anymore.由于脚本中创建的数据库和表不再可用。
Complete Docker Logs -->完整的 Docker 日志 -->
my-database | The files belonging to this database system will be owned by user "postgres".
my-database | This user must also own the server process.
my-database |
my-database | The database cluster will be initialized with locale "en_US.utf8".
my-database | The default database encoding has accordingly been set to "UTF8".
my-database | The default text search configuration will be set to "english".
my-database |
my-database | Data page checksums are disabled.
my-database |
my-database | fixing permissions on existing directory /var/lib/postgresql/data ... ok
my-database | creating subdirectories ... ok
my-database | selecting dynamic shared memory implementation ... posix
my-database | selecting default max_connections ... 100
my-database | selecting default shared_buffers ... 128MB
my-database | selecting default time zone ... Etc/UTC
my-database | creating configuration files ... ok
my-database | running bootstrap script ... ok
my-database | performing post-bootstrap initialization ... ok
my-database | syncing data to disk ... ok
my-database |
my-database | initdb: warning: enabling "trust" authentication for local connections
my-database | You can change this by editing pg_hba.conf or using the option -A, or
my-database | --auth-local and --auth-host, the next time you run initdb.
my-database |
my-database | Success. You can now start the database server using:
my-database |
my-database | pg_ctl -D /var/lib/postgresql/data -l logfile start
my-database |
my-database | waiting for server to start....2020-12-22 23:42:50.083 UTC [45] LOG: starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
my-database | 2020-12-22 23:42:50.085 UTC [45] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my-database | 2020-12-22 23:42:50.091 UTC [46] LOG: database system was shut down at 2020-12-22 23:42:49 UTC
my-database | 2020-12-22 23:42:50.096 UTC [45] LOG: database system is ready to accept connections
my-database | done
my-database | server started
my-database | CREATE DATABASE
my-database |
my-database |
my-database | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init-db-01.sql
my-database | psql:/docker-entrypoint-initdb.d/init-db-01.sql:1: NOTICE: database "mergeletter" does not exist, skipping
my-database | DROP DATABASE
my-database | CREATE DATABASE
my-database | You are now connected to database "mergeletter" as user "admin".
my-database | CREATE SEQUENCE
my-database | CREATE TABLE
my-database |
my-database |
my-database | 2020-12-22 23:42:50.515 UTC [45] LOG: received fast shutdown request
my-database | waiting for server to shut down....2020-12-22 23:42:50.516 UTC [45] LOG: aborting any active transactions
my-database | 2020-12-22 23:42:50.521 UTC [45] LOG: background worker "logical replication launcher" (PID 52) exited with exit code 1
my-database | 2020-12-22 23:42:50.521 UTC [47] LOG: shutting down
my-database | 2020-12-22 23:42:50.541 UTC [45] LOG: database system is shut down
my-database | done
my-database | server stopped
my-database |
my-database | PostgreSQL init process complete; ready for start up.
my-database |
my-database | 2020-12-22 23:42:50.648 UTC [1] LOG: starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
my-database | 2020-12-22 23:42:50.649 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
my-database | 2020-12-22 23:42:50.649 UTC [1] LOG: listening on IPv6 address "::", port 5432
my-database | 2020-12-22 23:42:50.652 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my-database | 2020-12-22 23:42:50.657 UTC [73] LOG: database system was shut down at 2020-12-22 23:42:50 UTC
my-database | 2020-12-22 23:42:50.663 UTC [1] LOG: database system is ready to accept connections
Put simply, this happens on purpose;简而言之,这是故意发生的; the author does it as part of the initialization.作者将其作为初始化的一部分。
It looks like some answers can be found in the image's entrypoint shell script:看起来可以在图像的入口点 shell 脚本中找到一些答案:
_main() {
# if first arg looks like a flag, assume we want to run postgres server
if [ "${1:0:1}" = '-' ]; then
set -- postgres "$@"
fi
if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then
docker_setup_env
# setup data directories and permissions (when run as root)
docker_create_db_directories
if [ "$(id -u)" = '0' ]; then
# then restart script as postgres user
exec gosu postgres "$BASH_SOURCE" "$@"
fi
# only run initialization on an empty data directory
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
docker_verify_minimum_env
# check dir permissions to reduce likelihood of half-initialized database
ls /docker-entrypoint-initdb.d/ > /dev/null
docker_init_database_dir
pg_setup_hba_conf
# PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless
# e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS
export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"
docker_temp_server_start "$@"
docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
docker_temp_server_stop
unset PGPASSWORD
echo
echo 'PostgreSQL init process complete; ready for start up.'
echo
else
echo
echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization'
echo
fi
fi
exec "$@"
}
As for "why?"至于“为什么?” I think it's because of desire to run as a less-privileged user.我认为这是因为希望以特权较低的用户身份运行。
You can "solve" the problem by specifying a volume in the Compose file like so:您可以通过在 Compose 文件中指定一个卷来“解决”问题,如下所示:
volumes:
- ./data/pgsql:/var/lib/postgresql/data
Then, it will skip the routine to ensure DATABASE_ALREADY_EXISTS
.然后,它将跳过例程以确保DATABASE_ALREADY_EXISTS
。
Or, if that's not helpful--you can dig into the entrypoint script a bit more.或者,如果这没有帮助 - 您可以深入研究入口点脚本。
Thanks for the above tip from @TorEHagermann ( https://stackoverflow.com/a/65417566/5631863 ) I was able to resolve the problem.感谢@TorEHagermann 提供的上述提示( https://stackoverflow.com/a/65417566/5631863 )我能够解决问题。
The solution was to include the following:解决方案是包括以下内容:
volumes:
- ./data/pgsql:/var/lib/postgresql/data
Also, in my case, I needed to clear and refresh the data every time I started the container.此外,就我而言,每次启动容器时都需要清除和刷新数据。 So, I included the following in my shell script to delete the drive /data/pgsql :因此,我在 shell 脚本中包含以下内容以删除驱动器/data/pgsql :
rm -rf data
With that change, my docker-compose file looks like: version: '3.8'有了这个改变,我的 docker-compose 文件看起来像:版本:'3.8'
services:
my-database:
container_name: my-database
image: library/postgres:13.1
volumes:
- ./db/init-my-database.sql:/docker-entrypoint-initdb.d/init-db-01.sql
- ./data/pgsql:/var/lib/postgresql/data
environment:
- POSTGRES_DB=my-database
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
ports:
- 10040:5432
restart: always
networks:
- app-network
As mentioned above, the restart is intentional.如上所述,重新启动是有意的。 The reason is that changes in some of the database server settings need restart to take effect.原因是某些数据库服务器设置的更改需要重新启动才能生效。 The entrypoint init script is a convenient place for the queries that change these settings.入口点初始化脚本是更改这些设置的查询的方便位置。
eg例如
ALTER SYSTEM SET max_connections = 300;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.