使用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
相关产品推荐
相关产品推荐

