如何在 GitLab CI 中复用 PostgreSQL 种子数据?
结论
可以在同一条 GitLab CI pipeline 中添加一个种子数据 job。这个 job 启动 PostgreSQL,以及运行初始化命令所需的其他 services,执行现有的 npm 数据创建命令,再用 pg_dump 将数据库导出为 artifact。后续 job 各自启动 PostgreSQL service,并从 artifact 恢复数据,这样每个 job 都有独立的数据库副本。
GitLab CI 的 service 作用于单个 job。不同 job 不应依赖同一个运行中的 PostgreSQL 实例,也不应依赖共享的容器目录。把数据库逻辑备份作为 artifact 传递,再分别恢复,适合这个场景。
配置思路
种子 job 保留现有的 PostgreSQL、Minio 和应用 services,以及创建用户、组织和发布 blocks 的命令。数据创建完成后,导出数据库:
seed-database:
stage: test
image: node:YOUR_NODE_IMAGE
services:
- name: postgres:15
alias: database
# 保留初始化命令需要的 Minio 和应用 services
variables:
DATABASE_HOST: database
DATABASE_PORT: "5432"
# DATABASE_NAME、DATABASE_USER、DATABASE_PASSWORD
# 以及 POSTGRES_DB、POSTGRES_USER、POSTGRES_PASSWORD
# 使用项目中已有的配置
script:
- npm run scripts create-user -- --name "$BOT_ACCOUNT_NAME" --email "$BOT_ACCOUNT_EMAIL"
- npm run scripts organization create testOrg
- npm run scripts block publish 'blocks/*'
- pg_dump -Fc -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USER" -d "$DATABASE_NAME" -f seed.dump
artifacts:
paths:
- seed.dump
expire_in: 1 day
YOUR_NODE_IMAGE 是占位符,需要替换成项目实际使用的 Node image。运行 pg_dump 的 job image 必须包含 PostgreSQL 客户端工具。如果当前 image 不含 pg_dump,可以在其中安装与环境兼容的客户端,也可以改用包含客户端工具的自定义 image。实际配置中,还要等数据库就绪后再运行初始化命令和导出。
下游 job 通过 needs 获取 artifact,并把数据库恢复到自己启动的 PostgreSQL service 中:
validate-snippets:
stage: test
image: node:YOUR_NODE_IMAGE
needs:
- job: seed-database
artifacts: true
services:
- name: postgres:15
alias: database
# 每个需要 Minio 或应用 service 的 job,单独配置相应 service
variables:
DATABASE_HOST: database
DATABASE_PORT: "5432"
# DATABASE_NAME、DATABASE_USER、DATABASE_PASSWORD
# 与 PostgreSQL service 的配置保持一致
script:
- pg_restore --no-owner --no-privileges -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USER" -d "$DATABASE_NAME" seed.dump
- # 执行该 job 的命令
其他需要相同初始数据的 job,也可以依赖 seed-database,启动各自的 PostgreSQL service 并恢复 seed.dump。恢复前要确认数据库已经就绪,且 PostgreSQL service 已创建目标数据库。上面的配置假设目标数据库为空;如果数据库中已有对象,需要另行处理。
需要留意的范围
- 这种方式会在每条 pipeline 中运行一次种子 job,下游 job 使用它生成的 artifact。它不会在不同 pipeline 之间永久共享数据库。若要跨 pipeline 复用,需要另外设计备份存储、版本更新和清理方式。
pg_dump只备份 PostgreSQL 数据,不包含 Minio 对象、其他 service 的状态或 PostgreSQL 集群角色。如果测试依赖这些内容,需要为相应数据和 service 单独准备初始化或复制步骤。- 确认 artifact 的大小、保留时间和访问权限符合需要。数据库备份可能包含敏感数据,应使用适合 CI 环境的测试数据,并妥善管理凭据。
pg_restore会使用目标数据库当前用户创建对象。--no-owner --no-privileges可以避免恢复时沿用源环境的所有者和授权。如果备份涉及特殊扩展或权限要求,仍需检查恢复条件。
备注:内容仅供参考。
