我正在尝试在 docker 容器内运行两个 PSQL 脚本,我的想法是我想使用 docker healthcheck 功能来等待数据库准备好运行脚本,第一个创建自定义数据库,第二个是在该自定义数据库上运行
什么可能导致第一个脚本运行(创建数据库)但第二个脚本不运行?
这是 pg-server.Dockerfile
# Use official PostgreSQL image
FROM postgres:latest
# Copy the initialization scripts into the container
COPY ./00_init-database.sql /docker-entrypoint-initdb.d/
COPY ./01_create-tables.sql /docker-entrypoint-initdb.d/
docker-compose 文件有这个
services:
postgres:
build:
context: ./database
dockerfile: pg-server.Dockerfile
ports:
- "5432:5432"
volumes:
- ./database/pg_data:/docker-entrypoint-initdb.d/
environment:
POSTGRES_DB: cloud_parking_db
POSTGRES_USER: someUser
POSTGRES_PASSWORD: somePassword
INIT_DB: "true"
healthcheck:
test:
[
"CMD",
"pg_isready",
"-q",
"-d",
"cloud_parking_db",
"-U",
"someUser"
]
interval: 10s
timeout: 5s
retries: 5
networks:
- cp_network
当我 docker-compose build 和 up 时,正在创建数据库,但未创建表
这是 postgress 容器的日志
2024-03-31 15:49:14 The files belonging to this database system will be owned by user "postgres".
2024-03-31 15:49:14 This user must also own the server process.
2024-03-31 15:49:14
2024-03-31 15:49:14 The database cluster will be initialized with locale "en_US.utf8".
2024-03-31 15:49:14 The default database encoding has accordingly been set to "UTF8".
2024-03-31 15:49:14 The default text search configuration will be set to "english".
2024-03-31 15:49:14
2024-03-31 15:49:14 Data page checksums are disabled.
2024-03-31 15:49:14
2024-03-31 15:49:14 fixing permissions on existing directory /var/lib/postgresql/data ... ok
2024-03-31 15:49:14 creating subdirectories ... ok
2024-03-31 15:49:14 selecting dynamic shared memory implementation ... posix
2024-03-31 15:49:14 selecting default max_connections ... 100
2024-03-31 15:49:14 selecting default shared_buffers ... 128MB
2024-03-31 15:49:14 selecting default time zone ... Etc/UTC
2024-03-31 15:49:14 creating configuration files ... ok
2024-03-31 15:49:14 running bootstrap script ... ok
2024-03-31 15:49:14 performing post-bootstrap initialization ... ok
2024-03-31 15:49:15 syncing data to disk ... ok
2024-03-31 15:49:15
2024-03-31 15:49:15
2024-03-31 15:49:15 Success. You can now start the database server using:
2024-03-31 15:49:15
2024-03-31 15:49:15 pg_ctl -D /var/lib/postgresql/data -l logfile start
2024-03-31 15:49:15
2024-03-31 15:49:15 waiting for server to start....2024-03-31 20:49:15.075 UTC [48] LOG: starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-03-31 15:49:15 2024-03-31 20:49:15.078 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-03-31 15:49:15 2024-03-31 20:49:15.087 UTC [51] LOG: database system was shut down at 2024-03-31 20:49:14 UTC
2024-03-31 15:49:15 2024-03-31 20:49:15.094 UTC [48] LOG: database system is ready to accept connections
2024-03-31 15:49:15 done
2024-03-31 15:49:15 server started
2024-03-31 15:49:15 CREATE DATABASE
2024-03-31 15:49:15
2024-03-31 15:49:15
2024-03-31 15:49:15 /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
2024-03-31 15:49:15
2024-03-31 15:49:15 waiting for server to shut down...2024-03-31 20:49:15.300 UTC [48] LOG: received fast shutdown request
2024-03-31 15:49:15 .2024-03-31 20:49:15.302 UTC [48] LOG: aborting any active transactions
2024-03-31 15:49:15 2024-03-31 20:49:15.304 UTC [48] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1
2024-03-31 15:49:15 2024-03-31 20:49:15.304 UTC [49] LOG: shutting down
2024-03-31 15:49:15 2024-03-31 20:49:15.307 UTC [49] LOG: checkpoint starting: shutdown immediate
2024-03-31 15:49:15 2024-03-31 20:49:15.399 UTC [49] LOG: checkpoint complete: wrote 923 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.020 s, sync=0.064 s, total=0.095 s; sync files=301, longest=0.004 s, average=0.001 s; distance=4257 kB, estimate=4257 kB; lsn=0/1913078, redo lsn=0/1913078
2024-03-31 15:49:15 2024-03-31 20:49:15.405 UTC [48] LOG: database system is shut down
2024-03-31 15:49:15 done
2024-03-31 15:49:15 server stopped
2024-03-31 15:49:15
2024-03-31 15:49:15 PostgreSQL init process complete; ready for start up.
2024-03-31 15:49:15
2024-03-31 15:49:15 initdb: warning: enabling "trust" authentication for local connections
2024-03-31 15:49:15 initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
2024-03-31 15:49:15 2024-03-31 20:49:15.537 UTC [1] LOG: starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-03-31 15:49:15 2024-03-31 20:49:15.538 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2024-03-31 15:49:15 2024-03-31 20:49:15.538 UTC [1] LOG: listening on IPv6 address "::", port 5432
2024-03-31 15:49:15 2024-03-31 20:49:15.543 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-03-31 15:49:15 2024-03-31 20:49:15.550 UTC [64] LOG: database system was shut down at 2024-03-31 20:49:15 UTC
2024-03-31 15:49:15 2024-03-31 20:49:15.560 UTC [1] LOG: database system is ready to accept connections
2024-03-31 15:54:15 2024-03-31 20:54:15.550 UTC [62] LOG: checkpoint starting: time
2024-03-31 15:54:19 2024-03-31 20:54:19.911 UTC [62] LOG: checkpoint complete: wrote 46 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.324 s, sync=0.018 s, total=4.361 s; sync files=13, longest=0.008 s, average=0.002 s; distance=261 kB, estimate=261 kB; lsn=0/19544E8, redo lsn=0/19544B0
数据库脚本
00_init-database.sql
DO $$
BEGIN
IF current_setting('INIT_DB') = 'true' THEN
-- Drop the database if it already exists
IF EXISTS (SELECT 1 FROM pg_database WHERE datname = 'cloud_parking_db') THEN
DROP DATABASE cloud_parking_db;
END IF;
CREATE DATABASE cloud_parking_db;
END IF;
END $$;
和
01_create-tables.sql
有这个
DO $$
BEGIN
IF current_setting('INIT_DB') = 'true' THEN
BEGIN;
-- Create the ParkingUser table
CREATE TABLE ParkingUser (
UserId SERIAL PRIMARY KEY,
Username VARCHAR(50) NOT NULL,
Email VARCHAR(100) NOT NULL,
Password VARCHAR(255) NOT NULL,
Role VARCHAR(20) NOT NULL
);
-- Create the Country table
CREATE TABLE Country (
CountryId SERIAL PRIMARY KEY,
Name VARCHAR(100) NOT NULL
);
-- more tables
COMMIT ;
END IF;
END $$;
在您的 Compose 文件中
volumes:
- ./database/pg_data:/docker-entrypoint-initdb.d/
volumes:
始终隐藏挂载点上映像中的任何内容,因此当容器启动时,您将看到 pg_data
目录的内容,而不是您在映像中复制的脚本。
postgres
图像的入口点包装脚本循环遍历初始化脚本。如果 initdb 目录为空,则循环顶部的 shell 扩展将仅返回 *
,并且您将收到在启动日志中引用的 ignoring /docker-entrypoint-initdb.d/*
消息。
您通常不应在映像中的非空目录上挂载卷,删除此块应该会有所帮助。
从主机目录名来看,你的意思是这个用来持久化数据库数据吗?在这种情况下,您的右侧目录是错误的,而您想要
volumes:
- ./database/pg_data:/var/lib/postgresql/data
您看到的效果不是第一个 init 脚本运行,而是入口点脚本理解
POSTGRES_DB
环境变量并为您创建数据库。 (它永远不会存在,并且您不需要此脚本。)考虑通过应用程序框架的数据库迁移系统运行第二个脚本,以便您可以在数据库架构更改时增量运行它,这样它就不会存在特别与 Docker 相关。