Docker容器中PostgreSQL数据库web_dev不存在问题求助
问题排查:PostgreSQL数据库
web_dev不存在 问题场景
执行docker-compose up -d --build后服务启动成功,输出如下:
[+] Running 2/2 ✔ Container fastapi-tdd-docker-web-db-1 Running 0.0s ✔ Container fastapi-tdd-docker-web-1 Started
但执行docker-compose exec web-db psql -U postgres进入数据库后,执行\c web_dev切换数据库时出现错误:
connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "web_dev" does not exist Previous connection kept
提供的docker-compose.yml配置
version: '3.8' services: web: build: ./project command: uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000 volumes: - ./project:/usr/src/app ports: - 8004:8000 environment: - ENVIRONMENT=dev - TESTING=0 - DATABASE_URL=postgres://postgres:postgres@web-db:5432/web_dev - DATABASE_TEST_URL=postgres://postgres:postgres@web-db:5432/web_test depends_on: - web-db web-db: build: context: ./project/db dockerfile: Dockerfile expose: - 5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres
问题原因
PostgreSQL官方镜像默认仅创建POSTGRES_USER指定的用户,不会自动生成web_dev、web_test这类自定义数据库。当前web-db服务仅配置了用户名和密码,未指定初始数据库,也没有通过初始化脚本创建所需数据库,因此启动后只有默认的postgres数据库,以及与用户名同名的postgres数据库。
解决方法
方法一:通过环境变量创建初始数据库
修改web-db服务的环境变量,添加POSTGRES_DB指定要自动创建的初始数据库(这里指定web_dev):
web-db: build: context: ./project/db dockerfile: Dockerfile expose: - 5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=web_dev
方法二:通过初始化脚本创建多个数据库
如果需要同时创建web_dev和web_test两个数据库,可通过初始化脚本实现:
- 在
./project/db目录下创建init-db.sql脚本:
CREATE DATABASE web_dev; CREATE DATABASE web_test;
- 修改
web-db服务的配置,挂载该脚本到PostgreSQL的自动初始化目录/docker-entrypoint-initdb.d/:
web-db: build: context: ./project/db dockerfile: Dockerfile expose: - 5432 volumes: - ./project/db/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres
注意事项
- 若之前已启动过
web-db服务,PostgreSQL会保留已有的数据卷,不会重新执行初始化步骤。需先删除数据卷再重新构建:docker-compose down -v docker-compose up -d --build depends_on仅保证web服务在web-db之后启动,不保证PostgreSQL完全就绪。若web服务启动时数据库未准备好,可能出现连接失败,可在web服务的启动命令前添加等待脚本(如wait-for-it),确保数据库端口开放后再启动应用。
内容的提问来源于stack exchange,提问作者Siraj Samsudeen
相关产品推荐
相关产品推荐

