我正在开发一个 Python 项目,该项目使用 Docker Compose 和 Postgres 服务。
撰写/postgresql/Dockerfile:
FROM postgres:16.1-bullseye
COPY init.sql /docker-entrypoint-initdb.d/init.sql
compose/postgresql/init.sql:(基本帐户设置)
-- Create database & user
CREATE DATABASE ${POSTGRES_DB};
CREATE USER ${POSTGRES_USER} WITH ENCRYPTED PASSWORD ${POSTGRES_PASSWORD};
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_USER} WITH GRANT OPTION;
GRANT USAGE ON SCHEMA public TO ${POSTGRES_USER};
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${POSTGRES_USER};
-- Alter default privileges
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO ${POSTGRES_USER};
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO ${POSTGRES_USER};
docker-compose.yaml:(使用 Docker Compose V2)
services:
postgres:
build:
context: compose/postgresql
ports:
- "5432:5432"
environment:
- POSTGRES_USER=app-user
- POSTGRES_PASSWORD=S3cr3tP4ssw0rd
- POSTGRES_DB=app-db
python-service:
[...]
进行本地测试时,上面的环境变量在
docker-compose.yaml
文件中提供。 Python 服务在 Postgres 服务后 10 秒启动,这超出了需要,因为最多只需要 2-3 秒即可启动。然而,Postgres 容器由于无法解析 init.sql 文件而无法在本地启动的情况经常发生(每 10 次左右运行 1 次):
postgres-1 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
postgres-1 | psql:/docker-entrypoint-initdb.d/init.sql:2: ERROR: syntax error at or near "$"
postgres-1 | LINE 1: CREATE DATABASE ${POSTGRES_DB};
postgres-1 | ^
postgres-1 | 2024-05-07 08:13:10.214 UTC [61] ERROR: syntax error at or near "$" at character 17
postgres-1 | 2024-05-07 08:13:10.214 UTC [61] STATEMENT: CREATE DATABASE ${POSTGRES_DB};
postgres-1 exited with code 3
它以如此不确定的方式失败了?如果这是一个解析错误(如错误所示),它应该一直发生或根本不发生,但不是随机的。
这并没有真正阻止我,因为我可以重新启动容器,但我很好奇其原因,以便我最终可以修复它。
我自己不在生产中使用 docker 下的 PostgreSQL,但我怀疑变量永远不会被值替换,并且该脚本总是失败。
但是,如果重新启动容器,则 db 目录已经有文件,因此脚本将不会运行,并且第二次也不会出现错误。
官方文档不建议在 sql 脚本中替换特定于 docker 的参数(向下滚动到“初始化脚本”)