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

如何不依赖docker-compose在Dockerfile配置POSTGRES_PASSWORD并排查异常

PostgreSQL Docker部署相关问题解答

问题1:不使用docker-compose时,如何在Dockerfile中配置POSTGRES_PASSWORD环境变量?

有三种常见实现方式,各有适用场景:

  • 直接在Dockerfile中用ENV指令硬编码
    操作最简单,但密码会明文存储在镜像中,仅适合测试环境:

    FROM postgres:latest
    ENV POSTGRES_PASSWORD=mypassword
    # 其他镜像配置...
    
  • 构建时通过--build-arg动态传递
    避免在Dockerfile中写死密码,构建时传入,但镜像最终仍会包含该环境变量:

    1. 修改Dockerfile添加参数接收逻辑:
      FROM postgres:latest
      ARG POSTGRES_PASSWORD
      ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD
      # 其他镜像配置...
      
    2. 构建时传递密码参数:
      docker build --build-arg POSTGRES_PASSWORD=mypassword .
      
  • 运行时通过-e参数传递(生产环境推荐)
    不在Dockerfile中配置密码,启动容器时动态传入,密码不会存入镜像,安全性最高:

    docker run -d -e POSTGRES_PASSWORD=mypassword -p 5432:5432 your-postgres-image
    

问题2:先执行docker build .再docker-compose up时,出现'mytable不存在'的错误

问题根源

你的docker-compose.yml同时指定了image: postgres和build: .:

  • 手动执行docker build .会生成一个无标签的本地镜像
  • 执行docker-compose up时,Compose会优先使用你指定的image: postgres,直接拉取官方PostgreSQL镜像,而非你本地构建的包含初始化脚本的镜像
  • 官方镜像中没有你的seed.sql和copy-data.sh,因此不会创建mytable,导致查询报错

解决方法

方法1:构建时给镜像打标签,与docker-compose.yml中的image名称一致

  1. 构建镜像并指定标签(与yaml中image字段一致):
    docker build -t postgres .
    
  2. 再执行docker-compose up,此时Compose会使用你本地构建的带标签镜像

方法2:直接使用docker-compose构建镜像(推荐)

无需手动执行docker build,让Compose统一管理构建和运行流程,自动匹配镜像:

docker-compose up -d --build

方法3:修改docker-compose.yml指定自定义镜像名

将image字段改为自定义名称,避免与官方镜像重名:

services:
  postgres-example-pg-hba:
    image: my-custom-postgres  # 自定义镜像名称
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_USER=mysuperuser
      - POSTGRES_PASSWORD=mypassword
    build:
      context: .
    ports:
      - "5432:5432"
    restart: unless-stopped

构建并运行:

docker build -t my-custom-postgres .
docker-compose up

附用户提供的相关文件及操作

postgresql_data/data/init.table.csv

id,name,completed
1,Buy pen,false
2,Write letter,false
3,Post letter,false
4,Post letter,false

docker-compose.yml

services:
  postgres-example-pg-hba:
    image: postgres
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_USER=mysuperuser
      - POSTGRES_PASSWORD=mypassword
    build:
      context: .
    ports:
          - "5432:5432"
    restart: unless-stopped

Dockerfile

FROM postgres:latest

# copy-data.sh
COPY ./postgresql_data ./temp

# Copy init.table.csv to /var/lib/postgresql/data/init.table.csv 
#   - Wait for postgres build to have created folder: /var/lib/postgresql/data 
#   - Then on docker-entrypoint-initdb.d/copy-data.sh
COPY ./scripts/copy-data.sh /docker-entrypoint-initdb.d/copy-data.sh
# cp /temp/data/init.table.csv -u /var/lib/postgresql/data/init.table.csv 

# Initialise database with a create table
COPY ./scripts/seed.sql /docker-entrypoint-initdb.d/seed.sql
# CREATE TABLE IF NOT EXISTS mytable(
#   id SERIAL PRIMARY KEY,
#   name VARCHAR(500) NOT NULL,
#   completed BOOLEAN NOT NULL
# );
# COPY mytable FROM '/var/lib/postgresql/data/init.table.csv' DELIMITER ',' CSV HEADER;

成功运行的操作(docker-compose up --build)

docker-compose up -d --build
docker exec -it dockerise-postgres-postgres-example-pg-hba-1 psql -U mysuperuser -d mydb
select * from mytable;

输出:

id |     name     | completed
----+--------------+-----------
  1 | Buy pen      | f
  2 | Write letter | f
  3 | Post letter  | f
  4 | Post letter  | f
(4 rows)

失败的操作(先build再up)

docker-compose down
docker image rm postgres

docker build .
docker-compose up
docker exec -it dockerise-postgres-postgres-example-pg-hba-1 psql -U mysuperuser -d mydb
select * from mytable;

错误信息:

mydb=# select * from mytable;
ERROR:  relation "mytable" does not exist
LINE 1: select * from mytable;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:47:03