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

如何将嵌套目录下的.sql文件复制到PostgreSQL Docker初始化目录

解决Postgres Docker镜像启动自动执行嵌套目录SQL文件的问题

目录结构回顾

project-folder/
├── Dockerfolder/
│   └── Dockerfile
└── pg/
    ├── folder1/
    │   ├── 01-create-db.sql
    │   ├── 02-create-tables.sql
    │   └── 03-seed-data.sql
    └── folder2/
        ├── 01-create-db.sql
        ├── 02-create-tables.sql
        └── 03-seed-data.sql

方案一:平展复制所有SQL文件到docker-entrypoint-initdb.d

Postgres官方镜像只会执行docker-entrypoint-initdb.d目录直接存放的脚本,嵌套子目录里的文件不会被扫描。以下两种方法可实现遍历所有子目录并平展复制SQL文件:

方法1:Docker COPY通配符复制(Docker 17.05+)

在Dockerfile中添加:

FROM postgres:latest

# 递归匹配pg目录下所有子目录的.sql文件,直接复制到目标目录(不保留原结构)
COPY pg/**/*.sql /docker-entrypoint-initdb.d/

方法2:Shell命令遍历复制(兼容性更强)

如果Docker版本较低,用find命令遍历复制:

FROM postgres:latest

# 先复制整个pg目录到容器临时位置,再移动所有.sql文件到目标目录
COPY pg /tmp/pg
RUN find /tmp/pg -name "*.sql" -exec cp {} /docker-entrypoint-initdb.d/ \; && rm -rf /tmp/pg

方案二:其他预初始化Postgres数据库的方案

1. 预构建数据卷镜像

  • 先启动临时容器完成初始化,再将数据目录打包为镜像:
    # 启动临时容器
    docker run -d --name temp-postgres -e POSTGRES_PASSWORD=mysecret postgres:latest
    # 复制SQL文件到初始化目录并重启容器
    docker cp pg/ temp-postgres:/docker-entrypoint-initdb.d/
    docker restart temp-postgres
    # 等待初始化完成后,提交为预初始化镜像
    docker commit temp-postgres my-preinit-postgres
    # 清理临时容器
    docker stop temp-postgres && docker rm temp-postgres
    
    后续直接使用my-preinit-postgres镜像启动,无需重复执行初始化脚本,启动速度更快。

2. 自定义Entrypoint脚本

  • 编写custom-entrypoint.sh脚本,遍历执行所有SQL文件:
    #!/bin/bash
    set -e
    
    # 按文件名排序执行SQL脚本
    for sql_file in $(find /pg -name "*.sql" | sort); do
        echo "Running script: $sql_file"
        psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -f "$sql_file"
    done
    
    # 调用原Postgres启动脚本
    exec docker-entrypoint.sh "$@"
    
  • 在Dockerfile中配置:
    FROM postgres:latest
    COPY pg /pg
    COPY custom-entrypoint.sh /usr/local/bin/
    RUN chmod +x /usr/local/bin/custom-entrypoint.sh
    ENTRYPOINT ["custom-entrypoint.sh"]
    CMD ["postgres"]
    

3. Docker Compose内嵌初始化命令

在docker-compose.yml中直接通过命令遍历执行:

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: mysecret
    volumes:
      - ./pg:/pg
    command: >
      bash -c "
        for sql_file in \$(find /pg -name '*.sql' | sort); do
          psql -U postgres -d postgres -f \$sql_file;
        done;
        docker-entrypoint.sh postgres
      "

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:40:14