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

使用Docker构建Django项目时遭遇权限拒绝问题求助

问题描述

在使用Docker构建Django项目时,遇到以下权限相关错误:

/usr/local/lib/python3.13/site-packages/django/core/management/commands/makemigrations.py:160: RuntimeWarning: Got an error checking a consistent migration history performed for database connection 'default': unable to open database file

后续错误均与创建db.sqlite3数据库的权限有关。

相关配置文件

docker-compose.yml

version: "3.9"

services:
  puppint:
    build: .
    container_name: puppint_app
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - ./static:/app/static
    env_file:
      - ./api.env
    working_dir: /app
    command: >
      sh -c "python puppint.py"

Dockerfile

FROM python:3.13-slim AS builder

RUN mkdir /app

WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN pip install --upgrade pip

COPY requirements.txt /app/

RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.13-slim

RUN useradd -m -r appuser && \
   mkdir /app && \
   chown -R appuser /app

COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/

WORKDIR /app

COPY --chown=appuser:appuser . .

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

USER appuser

EXPOSE 8000

CMD ["python3 puppint.py"]

puppint.py(启动脚本)

import os
import subprocess
from time import sleep

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'puppint.settings')

import django
django.setup()
from django.contrib.auth.models import User

def run_command(command):
    try:
        subprocess.run(command, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        print(f"Error when executing '{command}': {e}")

def check_superuser():
    if not User.objects.filter(is_superuser=True).exists():
        print("No superuser in database!\n")
        username = input("Enter username: ")
        email = input("Enter e-mail: ")
        password = input("Enter password: ")
        User.objects.create_superuser(username, email, password)

def main():

    print_banner()
    sleep(1)

    run_command("python manage.py makemigrations app")
    run_command("python manage.py migrate")
    run_command("python manage.py collectstatic --noinput")

    check_superuser()

    run_command("python manage.py runserver 0.0.0.0:8000")

if __name__ == "__main__":
    main()
解决方案

问题核心是容器内运行的appuser对挂载的本地目录(以及数据库文件)没有读写权限,以下是针对性修复步骤:

1. 调整宿主机目录权限

容器内的appuser默认UID为1000(可通过docker exec puppint_app id appuser确认),需要确保本地项目目录的权限与容器用户匹配:

sudo chown -R 1000:1000 ./

此命令会将当前目录的所有权转移给UID/GID为1000的用户,与容器内appuser权限一致,确保其能在挂载目录内创建db.sqlite3文件。

2. 修复Dockerfile中的CMD格式错误

当前Dockerfile的CMD采用数组格式但写法错误,会导致命令无法执行,修改为:

CMD ["python3", "puppint.py"]

3. 优化静态文件与数据库的存储方式(可选,更稳定)

如果不想修改宿主机权限,可将数据库和静态文件放到Docker专属卷中,避免权限冲突:

修改docker-compose.yml

添加专属卷配置:

version: "3.9"

services:
  puppint:
    build: .
    container_name: puppint_app
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - static_volume:/app/static
      - db_volume:/app/db
    env_file:
      - ./api.env
    working_dir: /app
    command: >
      sh -c "python puppint.py"

volumes:
  static_volume:
  db_volume:

修改Django settings.py

将数据库路径指向卷内目录:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db' / 'db.sqlite3',
    }
}

此方式下,数据库文件会存储在Docker管理的db_volume中,appuser拥有完全权限,无需调整宿主机目录权限。

4. 确保容器内目录权限配置完整

在Dockerfile中提前创建所需目录并设置权限,避免因目录不存在导致的权限问题:

RUN useradd -m -r appuser && \
    mkdir -p /app /app/static /app/db && \
    chown -R appuser /app

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:42:16