Настройки для статических и медиа файлов
Статическими файлами называют файлы CSS, JS и изображений, т.е. все файлы, которые не изменяются динамически, их содержание не зависит от контекста запроса и будет одинаково для всех пользователей.
Медиа файлами называют файлы изображений, аудио и видео файлы, т.е. все файлы, которые были загружены пользователями через Django.
Настройки для этих файлов выполняются в файле settings.py. Нам нужно определить некоторые переменные для Django:
# url директории статических файлов
STATIC_URL = "/static/"
# Путь до директории статических файлов
STATIC_ROOT = BASE_DIR / "static"
# url директории медиа файлов
MEDIA_URL = "/media/"
# Путь до директории медиа файлов
MEDIA_ROOT = BASE_DIR / "media"
Обратите внимание, что у вас уже будет переменная STATIC_URL в файле настроек settings.py, и вы должны избежать дублирования этой переменной.
Эти папки будут работать в контейнерах по пути /home/app/web/static и /home/app/web/media.
Так как эти файлы могут быть использованы как Nginx, так и Django мы создадим 2 тома в Docker и подключим их к обоим контейнерам:
version: '3.8'
services:
web:
# Берем Dockerfile из каталога app
build:
context: ./app
dockerfile: Dockerfile.prod
# Запускаем сервер gunicorn
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
# Слушаем порт 8000
expose:
- 8000
# Подключаем статические и медиа файлы
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
# Файл содержащий переменные для контейнера
env_file:
- .env.prod
# Дожидаемся запуска контейнера db и memcached
depends_on:
- db
- memcached
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=book_django
- POSTGRES_PASSWORD=pass_book_django
- POSTGRES_DB=book_django
memcached:
image: memcached:1.6.21
ports:
- 11211:11211
nginx:
build: ./nginx
# Подключаем статические и медиа файлы
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
ports:
- 80:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
Чтобы у нас не было проблем с правами (эти папки будут проброшены с правами для root) мы должны создать аналогичные папки в контейнере используя app/Dockerfile.prod.
Допишите следующие инструкции в месте где происходит создание каталога для приложения:
RUN mkdir $APP_HOME/static
RUN mkdir $APP_HOME/media
В результате наш app/Dockerfile.prod должен выглядеть следующим образом:
###########
# BUILDER #
###########
FROM python:3.12.0-alpine as builder
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# установка зависимостей
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev
RUN pip install --upgrade pip
# установка зависимостей
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
#########
# FINAL #
#########
FROM python:3.12.0-alpine
# создаем директорию для пользователя
RUN mkdir -p /home/app
# создаем отдельного пользователя
RUN addgroup -S app && adduser -S app -G app
# создание каталога для приложения
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/static
RUN mkdir $APP_HOME/media
WORKDIR $APP_HOME
# установка зависимостей и копирование из builder
RUN apk update && apk add libpq
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*
# копирование entrypoint-prod.sh
COPY ./entrypoint.prod.sh $APP_HOME
# копирование проекта Django
COPY . $APP_HOME
# изменение прав для пользователя app
RUN chown -R app:app $APP_HOME
# изменение рабочего пользователя
USER app
# установим права и запустим скрипт проверки запуска БД
RUN chmod +x /home/app/web/entrypoint.prod.sh
ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
Так же нужно изменить файл конфигурации Nginx что он тоже мог обращаться к этим папкам:
upstream htmx_book {
# Список бэкэнд серверов для проксирования
server web:8000;
}
server {
listen 80;
# Ваш домен
server_name 127.0.0.1;
# Параметры проксирования
location / {
# Если будет открыта корневая страница
# все запросу пойдут к одному из серверов
# в upstream htmx_book
proxy_pass http://htmx_book;
# Устанавливаем заголовки
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# Отключаем перенаправление
proxy_redirect off;
}
# подключаем статические файлы
location /static/ {
alias /home/app/web/static/;
}
# подключаем медиа файлы
location /media/ {
alias /home/app/web/media/;
}
}
В следующем шаге мы создадим образы и соберем статические файлы.