add: развертывание (1) - в dev-окружении все ок!
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Исключаем мусор и локальные артефакты, чтобы Docker-контекст был компактным.
|
||||
|
||||
# Git и IDE-файлы в образ не нужны.
|
||||
.git
|
||||
.github
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
# Секреты и локальные настройки не должны попадать в контейнерный контекст.
|
||||
.env
|
||||
.env.*
|
||||
.env.sample
|
||||
|
||||
# Виртуальное окружение и служебные артефакты Python.
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.log
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
.coverage*
|
||||
htmlcov/
|
||||
.tox/
|
||||
|
||||
# Локальные базы и дампы SQLite в контейнер не тащим.
|
||||
*.sqlite3
|
||||
database/
|
||||
media/
|
||||
|
||||
# Локальная сборка фронтенда пока не нужна в Docker-контексте.
|
||||
# Если позже соберём frontend внутри Docker, это правило можно пересмотреть.
|
||||
frontend-assembly/
|
||||
|
||||
# Загруженные медиа-файлы монтируются отдельно и не должны раздувать контекст.
|
||||
public/media/
|
||||
|
||||
# Документация и служебные git-ignore-файлы не нужны в runtime-образе.
|
||||
*.md
|
||||
**/.gitignore
|
||||
|
||||
# Репозиторные и оркестрационные файлы не нужны внутри runtime-образа.
|
||||
.gitea/
|
||||
.junie/
|
||||
_blueprint/
|
||||
docker-compose*.yml
|
||||
|
||||
# В принцепе, Dockerfile тоже можно исключить из контейнера, но для BuildKit это иногда ломает сборку
|
||||
# и считается антипаттерном, а так же может приводить к предупреждениям при сборке.
|
||||
# Dockerfile
|
||||
|
||||
+9
-3
@@ -2,10 +2,16 @@
|
||||
# Скопируй этот файл в `.env` и заполни реальными значениями.
|
||||
|
||||
DJANGO_DEBUG=True
|
||||
DJANGO_SECRET_KEY=CHANGE_ME
|
||||
DJANGO_ALLOWED_HOSTS=127.0.0.1,localhost,hypn0.ru
|
||||
DJANGO_ALLOWED_HOSTS=127.0.0.1,localhost,hypn0.xyz
|
||||
DJANGO_ADMINS=hypn0:admin@example.com
|
||||
DJANGO_CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8000,http://localhost:8000,https://hypn0.ru
|
||||
DJANGO_CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8000,http://localhost:8000,https://hypn0.xyz
|
||||
|
||||
# ====== Получить код для Django:
|
||||
# poetry run python hypn0/manage.py shell
|
||||
# Затем выполнить две строчки кода:
|
||||
# from django.core.management.utils import get_random_secret_key
|
||||
# print(get_random_secret_key())
|
||||
DJANGO_SECRET_KEY=CHANGE_ME
|
||||
|
||||
# Имя файла SQLite-базы. Путь всегда собирается через `BASE_DIR.parent / 'database'`.
|
||||
DJANGO_SQLITE_NAME=hypn0-db.sqlite3
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
name: HYPN0 Build and Push Docker Image
|
||||
run-name: HYPN0 Build and Push Docker Image ${{ github.ref_name }}
|
||||
|
||||
on:
|
||||
push:
|
||||
# Запускать сборку только при создании тега, начинающегося с 'v' (например, v1.0.0, v2.3.1)
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
env:
|
||||
REGISTRY: git.cube2.ru
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest # Или метка вашего раннера, если он специфичный (например, macos или self-hosted)
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Настройка QEMU для мультиплатформенной сборки (если нужно собирать под разные архитектуры)
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
# Настройка Docker Buildx (обязательно для build-push-action)
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
# Логин в реестр Gitea
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
# Извлечение метаданных (тегов и лейблов) для Docker
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
|
||||
|
||||
# Сборка и отправка образа
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
push: true
|
||||
# Собираем под текущую архитектуру (linux/amd64).
|
||||
# Если сервер и MacMini на разных архитектурах (x86 vs ARM), добавьте нужные, например: linux/amd64,linux/arm64
|
||||
# platforms: linux/amd64,linux/arm64
|
||||
# ---
|
||||
# Собираем только под linux/amd64 (для скорости)
|
||||
platforms: linux/amd64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# ДОБАВЛЕНО для медленного интернета и оптимизации сборки:
|
||||
cache-from: type=registry
|
||||
# cache-from: type=gha
|
||||
cache-to: type=registry,mode=max
|
||||
# cache-to: type=gha,mode=max
|
||||
timeout: 1800 # Увеличено до 30 минут на всю сборку
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
# =================================================
|
||||
# STAGE 1: Builder - Установка зависимостей
|
||||
# =================================================
|
||||
FROM python:3.14-slim AS builder
|
||||
|
||||
# Устанавливаем переменные окружения
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PIP_DEFAULT_TIMEOUT=100
|
||||
|
||||
# ENV POETRY_VERSION=2.1.1
|
||||
# ENV POETRY_HOME="/opt/poetry"
|
||||
# ENV POETRY_NO_INTERACTION=1
|
||||
# ENV POETRY_VIRTUALENVS_IN_PROJECT=true
|
||||
|
||||
# Устанавливаем Poetry
|
||||
RUN pip install --no-cache-dir --default-timeout=100 --retries 10 poetry poetry-plugin-export
|
||||
|
||||
# Создаем рабочую директорию
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем только файлы зависимостей для кэширования этого слоя
|
||||
COPY pyproject.toml poetry.lock /app/
|
||||
|
||||
# Экспортируем lock-файл в requirements.txt и ставим зависимости через pip.
|
||||
# Это обычно быстрее и проще для Docker, чем полноценная установка через Poetry.
|
||||
RUN poetry export --format requirements.txt --without-hashes --with dev --output /tmp/requirements.txt \
|
||||
&& pip install --no-cache-dir --default-timeout=100 --retries 10 -r /tmp/requirements.txt
|
||||
|
||||
|
||||
# =================================================
|
||||
# STAGE 2: Final - Создание чистого и безопасного образа
|
||||
# =================================================
|
||||
FROM python:3.14-slim AS stage-final
|
||||
|
||||
# Устанавливаем переменные окружения
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV DJANGO_SETTINGS_MODULE=hypn0.settings
|
||||
ENV PYTHONPATH="/home/app/web/hypn0"
|
||||
ENV HOME="/home/app"
|
||||
|
||||
|
||||
# Создаем пользователя без прав root для безопасности
|
||||
# RUN addgroup --system app && adduser --system --ingroup app app
|
||||
|
||||
# Создаем рабочую директорию
|
||||
WORKDIR /home/app/web
|
||||
|
||||
# Копируем установленные Python-пакеты из builder-стадии
|
||||
# Каталог /usr/local/bin нужен для бинарных файлов, таких как gunicorn, pytest, whitenoise и т.п.
|
||||
COPY --from=builder /usr/local/bin /usr/local/bin
|
||||
#Каталог /usr/local/lib/python3.14/site-packages нужен для обычных Python-пакетов и батареек
|
||||
COPY --from=builder /usr/local/lib/python3.14/site-packages /usr/local/lib/python3.14/site-packages
|
||||
|
||||
# Копируем исходный код проекта и устанавливаем правильного владельца
|
||||
# ИЗМЕНЕНИЕ: app:app -> 1000:1000
|
||||
COPY --chown=1000:1000 . .
|
||||
|
||||
# 1. Создаём директорию для конфигов nginx и даём права пользователю app
|
||||
# Это выполняется ещё от root, поэтому проблем с permissions не будет.
|
||||
# 2. Создаём директорию для собранной статики и даём права пользователю app.
|
||||
# `STATIC_ROOT` в settings.py живёт внутри `public`.
|
||||
# 3. Создаём директорию для ошибок (404, 500) и даём права пользователю app
|
||||
# 4. Создаём директорию для БД и даём права пользователю app
|
||||
# Это важно когда БД монтируется как том с хоста
|
||||
RUN mkdir -p /home/app \
|
||||
/nginx_configs_host/nginx \
|
||||
/home/app/web/public/staticfiles \
|
||||
/home/app/web/public/media/_error \
|
||||
/home/app/web/database && \
|
||||
chown -R 1000:1000 /nginx_configs_host /home/app/web/public /home/app/web/database
|
||||
|
||||
# Переключаемся на пользователя без прав root
|
||||
USER 1000
|
||||
|
||||
|
||||
# Собираем статику
|
||||
# Используем dummy ключ, так как .env файла нет на этапе сборки
|
||||
RUN SECRET_KEY=dummy python hypn0/manage.py collectstatic --noinput --clear
|
||||
|
||||
# Открываем порт
|
||||
EXPOSE 8000
|
||||
|
||||
# Проверка здоровья контейнера
|
||||
# Docker будет периодически проверять, жив ли контейнер, отправляя GET запрос к главной странице.
|
||||
# Параметры:
|
||||
# --interval=30s - проверка каждые 30 секунд
|
||||
# --timeout=3s - ожидаем ответ максимум 3 секунды
|
||||
# --start-period=10s - даем контейнеру 10 секунд на запуск перед первой проверкой
|
||||
# --retries=3 - объявляем контейнер unhealthy после 3 неудачных попыток
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
||||
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/').read()" || exit 1
|
||||
|
||||
# Переходим в директорию с manage.py для корректного запуска gunicorn
|
||||
WORKDIR /home/app/web/hypn0
|
||||
|
||||
# Команда запуска (два воркера для лучшей производительности, можно увеличить до число ядер на хосте)
|
||||
CMD ["python", "-m", "gunicorn", "--workers", "2", "--bind", "0.0.0.0:8000", "hypn0.wsgi:application"]
|
||||
@@ -0,0 +1,147 @@
|
||||
# config/nginx/hypn0-app--external-nginx.conf
|
||||
# ==============================================================================
|
||||
# ЭТАЛОННЫЙ КОНФИГУРАЦИОННЫЙ ФАЙЛ NGINX (Reverse Proxy для Docker)
|
||||
# ==============================================================================
|
||||
#
|
||||
# ВНИМАНИЕ:
|
||||
# Этот файл является шаблоном. При первом деплое он копируется в `/home/user/app/hypn0-site/config/nginx/hypn0-app--external-nginx.conf`,
|
||||
# а затем (уже руками) через силинк в `/etc/nginx/sites-available/` и активируется.
|
||||
# При последующих деплоях он НЕ ПЕРЕЗАПИСЫВАЕТСЯ автоматически, чтобы не затереть SSL-сертификаты и ручные правки.
|
||||
#
|
||||
# Если вы изменили этот файл в репозитории и хотите применить изменения на проде:
|
||||
# вам нужно обновить файл в `/home/user/app/hypn0-site/config/nginx/hypn0-app--external-nginx.conf` вручную (diff + copy).
|
||||
#
|
||||
# Так же (рядом) будет создан образец этого файла `nginx_hypn0.conf.example`, который будет обновляться при деплоях
|
||||
# из репозитория, чтобы вы могли видеть, что изменилось и при необходимости перенести эти изменения на прод.
|
||||
#
|
||||
# Предполагаемая структура на сервере:
|
||||
# /home/user/app/hypn0-site/
|
||||
# ├── docker-compose.yml
|
||||
# ├── .env
|
||||
# ├── media/ <-- Сюда Nginx смотрит напрямую (Docker volume)
|
||||
# └── ...
|
||||
|
||||
# 1. Описываем, где живет наш Django в Docker
|
||||
upstream hypn0-django {
|
||||
# Мы пробрасываем порт 8050 из контейнера наружу (в docker-compose.yml имя сервиса 'web', контейнер 'hypn0-backend')
|
||||
server 127.0.0.1:8042;
|
||||
keepalive_requests 200;
|
||||
}
|
||||
|
||||
# 2. Конфигурируем сервер
|
||||
server {
|
||||
server_name hypn0.xyz; # Основное доменное имя
|
||||
|
||||
# Слушаем 80 порт (Certbot потом добавит сюда редирект на 443 и настройки SSL)
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
charset utf-8;
|
||||
client_max_body_size 10M; # Разрешаем загрузку не слишком больших картинок
|
||||
|
||||
# Логи (пути могут отличаться в зависимости от настроек сервера, здесь стандартные для Ubuntu)
|
||||
access_log /var/log/nginx/hypn0.access.log;
|
||||
error_log /var/log/nginx/hypn0.error.log;
|
||||
|
||||
# --- GZIP (Сжатие) ---
|
||||
# Очень важно для динамического HTML от Django, который Gunicorn отдает несжатым.
|
||||
gzip on;
|
||||
gzip_vary on; # Добавляет заголовок Vary: Accept-Encoding
|
||||
gzip_proxied any; # Сжимать ответы, даже если мы за прокси
|
||||
gzip_comp_level 6; # Оптимальный баланс скорость/сжатие
|
||||
gzip_min_length 1000; # Не сжимать совсем мелочь
|
||||
# Типы файлов для сжатия (HTML сжимается автоматически, его писать не нужно)
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/json
|
||||
application/xml
|
||||
application/xml+rss
|
||||
image/svg+xml
|
||||
image/x-icon
|
||||
application/vnd.ms-fontobject
|
||||
font/woff
|
||||
font/woff2;
|
||||
|
||||
# --- МЕДИА ФАЙЛЫ (Загруженный контент) ---
|
||||
# Nginx отдает их напрямую с диска хоста, не дергая Docker.
|
||||
# Путь должен совпадать с тем, где лежит volume на хост-машине.
|
||||
# ВАЖНО: Убедитесь, что пользователь nginx (www-data) имеет права на чтение этой папки!
|
||||
# ТРЕБУЕТСЯ ЗАМЕНА ПРИ ДЕПЛОЕ: /home/user/app/hypn0-site -> ваш реальный путь
|
||||
location /media/ {
|
||||
alias /home/user/app/hypn0-site/media/;
|
||||
expires 30d; # Кешируем картинки на месяц
|
||||
add_header Cache-Control "public, no-transform";
|
||||
}
|
||||
|
||||
# --- СТРАНИЦЫ ОШИБОК (Custom Error Pages) ---
|
||||
# Если Django упал (502) или сработал тайм-аут (504), Nginx должен отдать статический HTML.
|
||||
# Эти файлы должны лежать в папке, доступной Nginx (например, в `media/_error`).
|
||||
#
|
||||
# ВАЖНО:
|
||||
# 1. Файлы 50x.html (500, 502, 503, 504) копируются в `media/_error` при старте контейнера (см. docker-compose.prod.yml -> command).
|
||||
# 2. error_page директива перехватывает ошибки от апстрима (Gunicorn).
|
||||
error_page 500 /500.html;
|
||||
error_page 502 /502.html;
|
||||
error_page 503 /503.html;
|
||||
error_page 504 /504.html;
|
||||
|
||||
location = /500.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /502.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /503.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /504.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
|
||||
# 404 (и другие) тоже нужно кастомизировать... обычно Django сам отдает 404.
|
||||
# Но, например, Nginx отдаст 404 при ошике доступа к media-файлам (они храняться на хосте, а не в контейнере)
|
||||
error_page 400 /400.html;
|
||||
error_page 401 /401.html;
|
||||
error_page 403 /403.html;
|
||||
error_page 404 /404.html;
|
||||
error_page 413 /413.html;
|
||||
error_page 429 /429.html;
|
||||
|
||||
location = /400.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /401.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /403.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /404.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /413.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
location = /429.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
|
||||
# Указываем единую страницу (на реконструкции) для всех прочих ошибок
|
||||
error_page 405 406 407 408 409 410 411 412 414 415 416 417 418 421 422 423 424 425 426 428 431 451 /under_reconstruction.html;
|
||||
location = /under_reconstruction.html { root /home/user/app/hypn0-site/media/_error; internal; }
|
||||
|
||||
# --- ВСЁ ОСТАЛЬНОЕ (Django + WhiteNoise) ---
|
||||
# Статика (/static/), robots.txt, favicon.ico и сам сайт обрабатываются внутри контейнера.
|
||||
# Nginx просто прокидывает запрос внутрь.
|
||||
location / {
|
||||
proxy_pass http://hypn0-django;
|
||||
|
||||
# Передаем правильные заголовки, чтобы Django знал реальный IP и протокол
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Если нужно чтобы Django обрабатывал и HTTP, и HTTPS, то можно раскомментировать эту строку
|
||||
# и передавать реальный протокол от клиента
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Явно указываем https, потому что клиент всегда приходит по HTTPS к Nginx
|
||||
# Даже если внутри контейнера это HTTP на 127.0.0.1:8050, для Django это должно быть HTTPS
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
|
||||
# Тайм-ауты (важно для долгих операций, если они есть)
|
||||
proxy_read_timeout 180s;
|
||||
proxy_connect_timeout 180s;
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Редирект с www на без-www (SEO best practice)
|
||||
# server {
|
||||
# server_name www.hypn0.ru;
|
||||
# listen 80;
|
||||
# return 301 $scheme://hypn0.ru$request_uri; # Всегда редиректим на основной домен
|
||||
# }
|
||||
@@ -0,0 +1,69 @@
|
||||
# ==============================================================================
|
||||
# Docker Compose для РАЗРАБОТКИ (Local Development)
|
||||
# Этот файл содержит настройки для локальной работы (live reload, debug).
|
||||
# Запуск: docker compose -f docker-compose.local up --build
|
||||
# ==============================================================================
|
||||
|
||||
services:
|
||||
web:
|
||||
# Имя контейнера для удобства
|
||||
container_name: hypn0-backend-dev
|
||||
|
||||
# Сборка из текущей директории
|
||||
build: .
|
||||
|
||||
# Проброс портов (чтобы сайт был доступен на localhost:8042)
|
||||
ports:
|
||||
- "8042:8000"
|
||||
|
||||
# 1. КОМАНДА ЗАПУСКА (Dev режим)
|
||||
# 1.A. Запускаем миграции, чтобы база была актуальной.
|
||||
# 1.B. Запускаем кастомную команду rehash, чтобы обновить id-хэши для SVG-генераций в соответствии
|
||||
# с HASHIDS_SALT из текущего .env
|
||||
# 1.C. Запускаем Gunicorn с 1 воркером и включаем --reload для авто-перезагрузки при изменении кода.
|
||||
# Уменьшаем число воркеров до 1 (ресурсы dev-машины можно не экономит, но одного достаточно).
|
||||
# Убираем collectstatic (в dev Django сам может отдавать статику или она нам не так важна сжатой)
|
||||
command: >
|
||||
sh -c "python manage.py migrate --noinput &&
|
||||
python manage.py rehash &&
|
||||
python -m gunicorn --workers 1 --bind 0.0.0.0:8000 --reload hypn0.wsgi:application"
|
||||
|
||||
# 2. МОНТИРОВАНИЕ КОДА (Live Reload)
|
||||
# Подключаем локальные папки внутрь контейнера, чтобы Gunicorn видел изменения без пересборки образа.
|
||||
volumes:
|
||||
# Монтируем основной код проекта.
|
||||
# Так как web, templates и manage.py лежат внутри hypn0/, одного этого маунта достаточно.
|
||||
- ./hypn0:/home/app/web/hypn0
|
||||
|
||||
# Монтируем всю папку public (Static + Media)
|
||||
# Это нужно, чтобы:
|
||||
# 1. Изменения в CSS/JS (public/static) сразу были видны (Live Reload).
|
||||
# 2. Загруженные картинки (public/media) сохранялись на диске.
|
||||
- ./public:/home/app/web/public
|
||||
|
||||
# Монтируем базу данных (чтобы данные сохранялись при пересоздании контейнера)
|
||||
# Используем ту же папку database, что и на проде, для единообразия.
|
||||
# ВАЖНО: Django ищет базу в BASE_DIR.parent / 'database/db.sqlite3'
|
||||
# В контейнере BASE_DIR=/home/app/web/hypn0, значит путь к базе: /home/app/web/database/db.sqlite3
|
||||
- ./database:/home/app/web/database
|
||||
|
||||
# 3. ПЕРЕМЕННЫЕ ОКРУЖЕНИЯ
|
||||
env_file:
|
||||
# файл с переменными окружения для разработки
|
||||
- .env
|
||||
environment:
|
||||
# на всякий случай, принудительно включаем DEBUG и DEBUG-уровень логов (вдруг в .env что-то не так)
|
||||
# - DJANGO_DEBUG=False
|
||||
- DJANGO_DEBUG=True
|
||||
- DJANGO_LOG_LEVEL=DEBUG
|
||||
# В dev нам не нужно ограничивать буферизацию так строго, но не помешает.
|
||||
|
||||
# 4. РЕСУРСЫ (Без лимитов для разработки)
|
||||
# Удаляем секцию ограничений, чтобы локально использовать все доступные ресурсы хоста.
|
||||
# deploy:
|
||||
# resources:
|
||||
# limits:
|
||||
# cpus: ...
|
||||
# memory: ...
|
||||
# mem_limit: ...
|
||||
|
||||
+2
-2
@@ -34,6 +34,7 @@ if settings.DEBUG:
|
||||
import mimetypes
|
||||
import debug_toolbar
|
||||
from django.views.static import serve
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
def _serve_public_root_file(request, path):
|
||||
"""Отдаёт файлы из корня `public` в dev-режиме в utf-8."""
|
||||
@@ -68,5 +69,4 @@ if settings.DEBUG:
|
||||
|
||||
urlpatterns = [path('__debug__/', include(debug_toolbar.urls)), ] + urlpatterns
|
||||
urlpatterns = [*PUBLIC_ROOT_URLPATTERNS, *urlpatterns]
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.PUBLIC_DIR.joinpath('static'))
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
|
||||
Reference in New Issue
Block a user