Ubuntu 20.04下Django Docker环境PostgreSQL无法运行问题求助
Docker Compose在Ubuntu 20.04运行数据库错误排查(Windows 10正常)
项目配置信息
Django settings.py配置
DATABASES = { 'default': { 'ENGINE': env('SQL_ENGINE'), 'NAME': env('SQL_DATABASE'), 'USER': env('SQL_USER'), 'PASSWORD': env('SQL_PASSWORD'), 'HOST': env('SQL_HOST'), 'PORT': env('SQL_PORT'), } }
.env文件配置
SQL_ENGINE=django.db.backends.postgresql SQL_DATABASE=my_db SQL_USER=my_admin SQL_PASSWORD=my_api SQL_HOST=db SQL_PORT=5432
docker-compose.yml配置
version: '3.9' services: web: build: ./pets command: gunicorn pets.wsgi:application --bind 0.0.0.0:8000 volumes: - static_volume:/home/app/web/staticfiles - media_volume:/home/app/web/mediafiles expose: - 8000 env_file: - .env depends_on: - db db: image: postgres:12.0-alpine volumes: - postgres_data:/var/lib/postgresql/data/ env_file: - .env nginx: build: ./nginx volumes: - static_volume:/home/app/web/staticfiles - media_volume:/home/app/web/mediafiles ports: - "1337:80" depends_on: - web volumes: postgres_data: static_volume: media_volume:
Dockerfile配置
FROM python:3.10.0-alpine WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 RUN pip install --upgrade pip RUN apk update RUN apk add postgresql-dev gcc python3-dev musl-dev COPY requirements.txt . RUN pip install -r requirements.txt COPY entrypoint.sh . RUN sed -i 's/\r$//g' /usr/src/app/entrypoint.sh ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $HOME RUN mkdir $APP_HOME WORKDIR $APP_HOME COPY .. $APP_HOME RUN mkdir $APP_HOME/staticfiles RUN mkdir $APP_HOME/mediafiles RUN chmod +x /usr/src/app/entrypoint.sh ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
遇到的错误
FATAL: role "my_admin" does not exist- 将SQL_USER改为postgres后,出现:
FATAL: database "my_db" does not exist - 将SQL_DATABASE改为postgres后,仍出现:
django.db.utils.ProgrammingError: relation "auth_user" does not exist
问题原因与解决方案
核心问题分析
PostgreSQL官方镜像初始化时,只会通过专属环境变量自动创建指定的用户名和数据库,而非你自定义的SQL_*变量。Windows上能正常运行,大概率是之前已经手动初始化过数据库(执行过migrate),或者Docker卷中已保存初始化后的数据库数据;而Ubuntu是全新环境,卷为空,镜像无法自动生成所需的用户和数据库。
具体错误对应原因
- role "my_admin" does not exist:Postgres镜像默认仅创建
postgres用户,.env中的SQL_USER=my_admin不被镜像识别,因此不会自动创建该角色。 - database "my_db" does not exist:切换到
postgres用户后,默认只有postgres数据库,my_db未被创建,导致连接失败。 - relation "auth_user" does not exist:连接到默认的
postgres数据库后,该库为空,未执行Django数据库迁移,因此不存在auth_user表。
解决方案
1. 修改.env文件,适配Postgres镜像环境变量
Postgres镜像识别的专属环境变量为POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB,在.env中添加这些变量并与SQL_*对应:
SQL_ENGINE=django.db.backends.postgresql SQL_DATABASE=my_db SQL_USER=my_admin SQL_PASSWORD=my_api SQL_HOST=db SQL_PORT=5432 # 新增Postgres镜像所需变量 POSTGRES_USER=my_admin POSTGRES_PASSWORD=my_api POSTGRES_DB=my_db
启动容器时,镜像会自动创建my_admin用户和my_db数据库,与Django配置完全匹配。
2. 清理Ubuntu上的旧卷(若有残留数据)
如果之前在Ubuntu上启动过容器,可能卷中存在旧的无效数据,先清理:
docker-compose down -v
再重新构建启动:
docker-compose up --build
3. 确保执行数据库迁移
启动容器后,进入web容器执行Django迁移:
docker-compose exec web python manage.py migrate
也可以将迁移命令加入entrypoint.sh,确保容器启动时自动执行(注意避免重复迁移,可通过判断数据库状态添加逻辑)。
为什么Windows上正常?
Windows环境中之前运行时,可能已经:
- 手动执行过
migrate创建了数据库和表; - Docker卷已保存初始化后的数据库状态,再次启动时直接复用;
- 曾使用默认的
postgres用户和数据库,后续修改配置后卷中数据未被清空,仍可正常连接。
内容的提问来源于stack exchange,提问作者Anonymous Wizard
相关产品推荐
相关产品推荐

