如何在依赖容器启动后、目标服务启动前对Docker中postgres执行sql脚本
解决方案
核心思路
新增一个独立的临时初始化容器,作为configApi和myApi之间的启动衔接层,完全不改动原有两个业务服务的代码与内置配置,满足所有限制条件。
具体实现步骤
第一步:准备配置插入SQL脚本
在项目根目录新建insert-config-data.sql,写入需要插入到configApi对应库的配置数据,示例内容请根据实际的库名、表名、字段调整:-- 切换到configApi使用的独立数据库 \c config_api_db; -- 插入所需配置数据,表结构已由configApi的flyway迁移提前创建 INSERT INTO config_table (config_key, config_value) VALUES ('myapi.db.url', 'jdbc:postgresql://postgres:5432/my_api_db'), ('myapi.db.username', 'myapi_user'), ('myapi.db.password', 'myapi_pass');第二步:修改docker-compose.yml配置,共3处核心改动:
- 给configApi添加健康检查,确认它完全启动、flyway执行完成、服务处于可用状态
- 新增
config-data-init初始化容器,负责等待configApi就绪后执行SQL插入配置数据 - 调整myApi的启动依赖,改为等待初始化容器执行完成后再启动
修改后的完整docker-compose.yml如下:
version: "3" volumes: db_data: services: postgres: image: postgres:10.14 volumes: - ./init-local.sql:/docker-entrypoint-initdb.d/init.sql - db_data:/var/lib/postgresql ports: - 5432:5432 environment: # 按需配置postgres的默认账号密码,和init-local.sql对应即可 - POSTGRES_PASSWORD=postgres configApi: image: org/config-api:latest ports: - 8234:8234 environment: - DB_PORT=5432 - DB_HOST=postgres depends_on: - postgres # 新增健康检查,确认configApi完全就绪 healthcheck: # 若configApi开启了SpringBoot Actuator健康端点,用以下检测逻辑 test: ["CMD-SHELL", "curl -fs http://localhost:8234/actuator/health || exit 1"] # 若没有健康端点,可改用检测对应配置表是否已创建的逻辑,替换上面的test即可 # test: ["CMD-SHELL", "apt update && apt install -y postgresql-client && pg_isready -U postgres -h postgres && psql -U postgres -d config_api_db -c \"SELECT 1 FROM config_table LIMIT 1\" || exit 1"] interval: 5s timeout: 5s retries: 12 # 新增配置数据初始化容器 config-data-init: image: postgres:10.14 volumes: # 挂载插入数据的sql脚本 - ./insert-config-data.sql:/insert.sql depends_on: configApi: # 等待configApi健康检查通过再启动 condition: service_healthy postgres: condition: service_started # 启动后执行sql脚本,执行完成自动退出 command: ["psql", "-h", "postgres", "-U", "postgres", "-f", "/insert.sql"] environment: - PGPASSWORD=postgres myApi: build: ./my-api image: org/my-api:latest container_name: my-api ports: - 9080:9080 environment: - CONFIG_MANAGER_API_URL=http://configApi:8234/ depends_on: # 等待初始化容器执行完成再启动 config-data-init: condition: service_completed_successfully
关键逻辑说明
- 原有
depends_on仅判断容器是否处于运行状态,无法感知内部服务是否就绪,通过健康检查可以准确判断configApi的flyway迁移已完成、配置表已创建 - 初始化容器直接使用postgres官方镜像,自带psql客户端无需额外构建,执行完成后自动退出,不会额外占用运行资源
- 完全符合所有限制要求:未修改configApi、myApi的任何代码与内置配置,配置表依然由configApi的flyway创建,postgres初始化阶段未提前插入配置数据,myApi依然从configApi接口获取所有配置。
内容的提问来源于stack exchange,提问作者Igor Flakiewicz
相关产品推荐
相关产品推荐

