fixed docker

This commit is contained in:
afanasyev.aa 2025-06-26 20:47:12 +09:00
parent 741aefca31
commit c334c0628d
8 changed files with 206 additions and 40 deletions

36
.dockerignore Normal file
View file

@ -0,0 +1,36 @@
__pycache__
**/__pycache__
**/__pycache__/*
venv
*.pyc
*.pyo
*.pyd
*.sqlite3
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.vscode
.prettierrc
.mypy_cache
.pytest_cache
.hypothesis
Dockerfile
.env
.dockerignore
docker-compose.override.yml
docker-compose.override
docker-compose.yml
nginx
media
static
postgres

View file

@ -1,20 +1,76 @@
# Базовый образ
FROM python:3.11
FROM python:3.13-slim AS builder
RUN mkdir /www
WORKDIR /www
# Устанавливаем рабочую директорию внутри контейнера
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Копируем зависимости
COPY requirements.txt .
# Устанавливаем зависимости
# RUN apt-get update && apt-get install -y --no-install-recommends \
# libpq-dev \
# gcc \
# g++ \
# libffi-dev \
# libssl-dev \
# libxml2-dev \
# libxslt1-dev \
# zlib1g-dev \
# libjpeg-dev \
# libfreetype6-dev && \
# rm -rf /var/lib/apt/lists/* && \
# apt-get clean && \
# apt-get autoclean
RUN pip install --upgrade pip
COPY requirements.txt /www/
RUN pip install --no-cache-dir -r requirements.txt
# Копируем все файлы проекта
COPY . .
COPY requirements-prod.txt /www/
RUN pip install --no-cache-dir -r requirements-prod.txt
# Stage 2: Production stage
FROM python:3.13-slim
# Открываем порт (опционально, если хочешь)
EXPOSE 8000
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq-dev \
libssl-dev \
gettext && \
apt-get clean && \
apt-get autoclean
RUN useradd -m -r wwwuser && \
mkdir /www && \
chown -R wwwuser /www
# Copy the Python dependencies from the builder stage
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/
# Set the working directory
WORKDIR /www
# Copy application code
COPY --chown=wwwuser:wwwuser . .
# Запускаем сервер
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
RUN chmod +x /www/entrypoint.sh && \
chmod +x /www/manage.py
RUN mkdir -p /static && \
mkdir -p /media && \
chown -R wwwuser:wwwuser /static && \
chown -R wwwuser:wwwuser /media
# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Switch to non-root user
USER wwwuser
# Expose the application port
EXPOSE 8000
# Run Djangos development server
CMD ["/www/entrypoint.sh"]

View file

@ -1,3 +1,5 @@
version: '3.8'
services:
db:
image: postgres:14
@ -7,24 +9,40 @@ services:
POSTGRES_PASSWORD: mypass
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- app_network
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
volumes:
- ./static:/static:rw
- ./media:/media:rw
env_file: .env
depends_on:
- db
environment:
- DB_NAME=mydb
- DB_USER=myuser
- DB_PASSWORD=mypass
- DB_HOST=db
- DB_PORT=5432
networks:
- app_network
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./static:/var/www/static
- ./media:/var/www/media
depends_on:
- web
networks:
- app_network
volumes:
postgres_data:
static_volume:
media_volume:
networks:
app_network:
driver: bridge

4
entrypoint.sh Normal file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
python manage.py collectstatic --noinput
python manage.py migrate --noinput
python -m daphne testapi.asgi:application -b 0.0.0.0 -p 8000

34
nginx/nginx.conf Normal file
View file

@ -0,0 +1,34 @@
upstream django {
server web:8000;
}
server {
listen 80;
server_name localhost;
# Static files
location /static/ {
alias /app/static/;
expires 1y;
access_log off;
add_header Cache-Control "public";
gzip_static on;
}
# Media files
location /media/ {
alias /app/media/;
expires 7d;
access_log off;
add_header Cache-Control "public";
}
# Django app
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

1
requirements-prod.txt Normal file
View file

@ -0,0 +1 @@
daphne

View file

@ -6,4 +6,4 @@ drf-spectacular
requests
django-cors-headers
Pillow
python-dotenv

View file

@ -12,6 +12,9 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
from pathlib import Path
import os
from dotenv import load_dotenv
load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -19,16 +22,28 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
# Environment flag
PRODUCTION = os.getenv('DJANGO_ENV') == 'production'
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-np(nxnh6mw)v4pa2n2z3pl_5&!2z$jshhak9r3v=y1u9rd*sl!'
SECRET_KEY = os.getenv(
'SECRET_KEY', 'django-insecure-np(nxnh6mw)v4pa2n2z3pl_5&!2z$jshhak9r3v=y1u9rd*sl!')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = os.getenv('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = []
ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', 'localhost').split(',')
# Static files (CSS, JavaScript, Images)
STATIC_URL = os.getenv('STATIC_URL', '/static/')
STATIC_ROOT = os.getenv('STATIC_ROOT', os.path.join(BASE_DIR, 'static'))
# Media files (user uploaded)
MEDIA_URL = os.getenv('MEDIA_URL', '/media/')
MEDIA_ROOT = os.getenv('MEDIA_ROOT', os.path.join(BASE_DIR, 'media')) # Куда сохранять загруженные файлы
# Application definitionЫ
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
@ -89,22 +104,22 @@ WSGI_APPLICATION = 'testapi.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
if DEBUG:
if PRODUCTION:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('DB_NAME'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
'HOST': os.getenv('DB_HOST'),
'PORT': os.getenv('DB_PORT'),
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'drfapi', # Your database name
'USER': 'postgres', # Your PostgreSQL username
'PASSWORD': '1235', # Your PostgreSQL password
'HOST': 'localhost', # Or your DB server's IP
'PORT': '5432', # Default PostgreSQL port
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
@ -176,4 +191,6 @@ CSRF_COOKIE_SAMESITE = 'None' # temp
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_SAMESITE = 'None' # temp
SESSION_COOKIE_SECURE = False
CSRF_TRUSTED_ORIGINS = ['http://localhost:5173', 'http://127.0.0.1:5173']
CSRF_TRUSTED_ORIGINS = os.getenv('CSRF_TRUSTED_ORIGINS', '').split(',')