Docker部署Django+PostgreSQL时角色django2存在性矛盾问题
Django+Docker部署PostgreSQL角色冲突问题
问题现象
执行docker-compose up --build时触发数据库连接错误:
django.db.utils.OperationalError: FATAL: role "django2" does not exist
但手动执行CREATE ROLE django2;命令时,又返回角色已存在的提示:
ERROR: role "django2" already exists
相关配置
settings.py 数据库配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'zane_db', 'USER': 'django2', 'PASSWORD': 'django2', 'HOST': 'db', 'PORT': 5432 } }
docker-compose.yml 配置
version: '3.8' services: web: tty: true build: . command: python3 /docekr/manage.py runserver 0.0.0.0:8000 volumes: - .:/docekr ports: - 8000:8000 depends_on: - db db: image: postgres:11 volumes: - postgres_data:/var/lib/postgresql/data/ environment: - "POSTGRES_HOST_AUTH_METHOD=trust" volumes: postgres_data:
Dockerfile 配置
FROM python:3.9 ENV PYTHONUBBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 WORKDIR /zane COPY Pipfile Pipfile.lock /zane/ RUN pip3 install pipenv && pipenv install --system COPY . /zane/
注册视图代码(供参考)
letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9",] characters = letters + numbers length = 5 token = "".join(random.sample(characters, length)) def signup(request): if request.method == "POST": context = {'has_error': False, 'data': request.POST} global password global password2 global email global username email = request.POST.get('email') username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') body = render_to_string('authentication/email/email_body.html', { 'username': username, 'token': token, }) send_mail( "Email Confirmation", body, 'tadejtilinger@gmail.com', [email] ) return redirect('email-confirmation') return render(request, 'authentication/signup.html') def email_confirmation(request): if request.method == "POST": context = {'has_error': False, 'data': request.POST} code = request.POST.get('code') if code == token: if len(password) < 8: ############custom message context['has_error'] = True if password != password2: ############custom message context['has_error'] = True if not validate_email(email): ############custom message context['has_error'] = True if not username: ############custom message context['has_error'] = True if models.CustomUser.objects.filter(username=username).exists(): ############custom message context['has_error'] = True return render(request, 'authentication/signup.html', context, status=409) if models.CustomUser.objects.filter(email=email).exists(): ############custom message context['has_error'] = True return render(request, 'authentication/signup.html', context, status=409) if context['has_error']: return render(request, 'authentication/signup.html', context) user = models.CustomUser.objects.create_user(username=username, email=email) user.set_password(password) user.save() user = authenticate(request, username=username, password=password) login(request) return render(request, 'authentication/email/email_confirmation.html')
解决步骤
1. 清除PostgreSQL持久化数据卷
本地数据卷可能残留了不一致的角色状态,先彻底删除关联卷:
docker-compose down -v
2. 配置PostgreSQL自动初始化环境变量
PostgreSQL官方镜像支持通过环境变量自动创建用户、数据库,修改docker-compose.yml的db服务配置:
db: image: postgres:11 volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_USER=django2 - POSTGRES_PASSWORD=django2 - POSTGRES_DB=zane_db
容器启动时会自动创建匹配settings.py的用户和数据库,无需手动执行SQL。
3. 修正web服务路径拼写错误
Dockerfile中WORKDIR为/zane,但docker-compose.yml中路径拼写错误,统一修改为:
web: tty: true build: . command: python3 /zane/manage.py runserver 0.0.0.0:8000 volumes: - .:/zane ports: - 8000:8000 depends_on: - db
4. 重新构建启动服务
执行命令重新部署:
docker-compose up --build
额外提示:优化视图全局变量问题
注册视图中使用的global password、global email等全局变量,在多用户并发场景下会导致数据混乱。建议改用session存储临时数据,或创建EmailVerification模型存储验证记录(包含用户名、邮箱、token、过期时间等字段)。
内容的提问来源于stack exchange,提问作者P Studio
相关产品推荐
相关产品推荐

