You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Coolify中通过自定义初始化脚本正确初始化Docker化PostgreSQL数据库

问题分析与解决方案

核心原因

PostgreSQL官方镜像的/docker-entrypoint-initdb.d/目录下的脚本仅在数据目录首次初始化(为空)时执行一次。如果Coolify部署时复用了之前创建的db_data持久化卷(哪怕之前部署失败,卷内已有初始化残留数据),初始化脚本就会被跳过,导致数据库和用户未创建。


修复方案

方案1:让初始化脚本每次启动都执行(兼容已有数据卷)

修改脚本逻辑,使其不再依赖镜像的首次初始化机制,而是每次容器启动时都检查并补全数据库和用户:

  1. 修改init.sh脚本:
#!/bin/bash
set -e

# 替换SQL文件中的环境变量
envsubst < /docker-entrypoint.d/init.sql > /docker-entrypoint.d/init-user-db.sql

# 等待PostgreSQL服务完全启动
until pg_isready -U "$POSTGRES_USER" -h localhost; do
  echo "等待PostgreSQL服务启动..."
  sleep 2
done

# 执行初始化SQL
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" -f /docker-entrypoint.d/init-user-db.sql
  1. 修改PostgreSQL的Dockerfile:
    把脚本放到/docker-entrypoint.d/目录(该目录下的脚本会在每次容器启动时执行,而非仅首次):
FROM postgres:15

COPY db-init/init.sh /docker-entrypoint.d/init.sh
COPY db-init/init.sql /docker-entrypoint.d/init.sql

RUN chmod +x /docker-entrypoint.d/init.sh

方案2:修复原有初始化脚本的身份问题

原有脚本执行psql时使用了$POSTGRES_USER,但首次启动时该用户尚未创建,会导致权限错误。应改用默认的postgres超级用户执行初始化:

修改init.sh:

#!/bin/bash
set -e

envsubst < /docker-entrypoint-initdb.d/init.sql > /docker-entrypoint-initdb.d/init-user-db.sql

# 用默认postgres超级用户执行初始化(此时自定义用户还不存在)
psql -v ON_ERROR_STOP=1 --username "postgres" -f /docker-entrypoint-initdb.d/init-user-db.sql

方案3:强制重置Coolify的持久化卷

如果确认是旧数据卷导致脚本未执行,可在Coolify控制台中找到PostgreSQL服务的持久化存储配置,删除已有的db_data卷,重新触发部署,让初始化脚本重新执行。


额外优化建议

  1. 环境变量检查:确保Coolify部署环境中,POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB等变量已正确配置并传递给容器。
  2. 生产环境卷配置:删除NestJS服务中的- .:/app卷挂载,避免本地代码覆盖容器内的构建产物,导致版本不一致:
nest:
  build: .
  container_name: transfer_nest
  restart: always
  depends_on:
    - postgres
    - redis
  env_file:
    - .env
  ports:
    - '3000:3000'
  volumes:
    - /app/node_modules
  networks:
    - app_network

内容的提问来源于stack exchange,提问作者Bendito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:43:18