Django连接PostgreSQL容器数据库不存在及库创建问题
解决方案
一、实现Django应用与PostgreSQL容器连通
1. 修正docker-compose.yml配置
首先修正PostgreSQL数据卷挂载路径,同时添加数据库连接相关环境变量:
version: '3.8' services: app: build: context: . environment: - SECRET_KEY=changeme - ALLOWED_HOSTS=127.0.0.1,localhost # 新增数据库连接配置 - DB_HOST=db - DB_NAME=django_db - DB_USER=django_user - DB_PASSWORD=django_pass - DB_PORT=5432 depends_on: - db db: image: postgres:15 # 推荐指定固定版本避免兼容性问题 restart: always volumes: # 修正挂载路径,postgres默认数据目录为/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data ports: - 5432:5432 environment: # postgres官方镜像会用这些变量自动初始化数据库 - POSTGRES_DB=django_db - POSTGRES_USER=django_user - POSTGRES_PASSWORD=django_pass proxy: build: context: ./proxy volumes: - static_data:/vol/static ports: - 80:8080 depends_on: - app volumes: static_data: postgres_data: # 新增postgres专用数据卷
2. 修改Django数据库配置
修改settings.py中的DATABASES配置,从环境变量读取连接参数:
import os DATABASES = { 'default': { 'ENGINE': 'django.contrib.gis.db.backends.postgis', # 你安装了gdal依赖,直接用postgis引擎即可 'NAME': os.environ.get('DB_NAME'), 'USER': os.environ.get('DB_USER'), 'PASSWORD': os.environ.get('DB_PASSWORD'), 'HOST': os.environ.get('DB_HOST'), # 此处填docker compose的db服务名,内部DNS会自动解析 'PORT': os.environ.get('DB_PORT'), } }
3. 优化启动脚本等待数据库就绪
depends_on仅保证容器启动顺序,不会等PostgreSQL服务完全初始化完成,需要在entrypoint.sh中添加等待逻辑:
#!/bin/sh # 等待数据库端口就绪 while ! nc -z $DB_HOST $DB_PORT; do echo "等待数据库启动中..." sleep 1 done echo "数据库启动完成,执行迁移..." python manage.py migrate --noinput # 替换为你实际的Django启动命令 exec gunicorn your_project.wsgi:application --bind 0.0.0.0:8000
注意需要在requirements.txt中添加psycopg2-binary依赖,确保Django可以正常连接PostgreSQL。
二、独立PostgreSQL容器场景下创建所需数据库
PostgreSQL的数据库属于状态数据,无法在镜像构建阶段持久化写入(构建阶段的写入会在容器启动时被重置),推荐使用官方镜像的内置初始化机制:
- 官方PostgreSQL镜像会在首次启动容器时,自动执行
/docker-entrypoint-initdb.d/目录下的所有.sql、.sh脚本 - 如果你需要自定义初始化逻辑,只需要把脚本挂载或者打包到该目录即可,不需要额外修改基础逻辑
如果需要把初始化逻辑打包到PostgreSQL镜像中,可以新建独立的PostgreSQL Dockerfile:
FROM postgres:15 # 复制自定义初始化脚本到指定目录 COPY ./init.sql /docker-entrypoint-initdb.d/
init.sql示例:
-- 可执行自定义建表、授权、安装扩展等操作 CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS postgis_topology;
修改docker-compose.yml中的db服务build参数指向该Dockerfile即可,构建镜像时会把初始化脚本打包进去,首次启动容器自动执行。
内容的提问来源于stack exchange,提问作者swamper
相关产品推荐
相关产品推荐

