如何不依赖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中写死密码,构建时传入,但镜像最终仍会包含该环境变量:- 修改Dockerfile添加参数接收逻辑:
FROM postgres:latest ARG POSTGRES_PASSWORD ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD # 其他镜像配置... - 构建时传递密码参数:
docker build --build-arg POSTGRES_PASSWORD=mypassword .
- 修改Dockerfile添加参数接收逻辑:
运行时通过-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名称一致
- 构建镜像并指定标签(与yaml中
image字段一致):docker build -t postgres . - 再执行
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
相关产品推荐
相关产品推荐

