Перейти к основному содержимому

Требования к Dockerfile

Кластер работает с Pod Security Standards (restricted) — это значит контейнеры не могут запускаться от root. Следуй шаблонам ниже.

Backend (Django / FastAPI)​

FROM python:3.12-slim

WORKDIR /app

# Создать пользователя с UID 1000 — PSS restricted запрещает root
RUN groupadd -g 1000 app && useradd -u 1000 -g app app

COPY requirements.txt .
RUN pip install --no-cache-dir --index-url https://nexus.simple-env.site/repository/pypi-proxy/simple/ -r requirements.txt

COPY . .

# Статика собирается при сборке образа, не в runtime
# (в контейнере файловая система read-only)
RUN python manage.py collectstatic --noinput || true

USER app

EXPOSE 8000
CMD ["gunicorn", "config.wsgi:application", \
"--bind", "0.0.0.0:8000", "--workers", "2"]
Важно
  • USER app — обязательно, без него деплой упадёт
  • collectstatic — в Dockerfile, не в runtime
  • EXPOSE 8000 — порт должен совпадать с backend.port в deploy.yaml

Frontend (React + Vite → nginx)​

# Stage 1: сборка
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --silent --registry https://nexus.simple-env.site/repository/npm-proxy/
COPY . .
RUN npm run build

# Stage 2: nginx
FROM nginx:alpine
# nginx работает от пользователя nginx (UID 101) — не root
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

Файл nginx.conf:

# Файловая система контейнера read-only — логи только в stdout/stderr
access_log /dev/stdout;
error_log /dev/stderr warn;

server {
listen 80;
root /usr/share/nginx/html;
index index.html;

# SPA: все маршруты → index.html
location / {
try_files $uri $uri/ /index.html;
}

# Кэширование статики
location ~* \.(js|css|png|jpg|svg|ico)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
nginx и read-only файловая система

Не добавляй access_log /var/log/nginx/... или error_log /var/log/nginx/... — эта директория недоступна для записи в кластере. Используй /dev/stdout и /dev/stderr как в примере выше.

FastAPI (альтернатива Django)​

FROM python:3.12-slim

WORKDIR /app

RUN groupadd -g 1000 app && useradd -u 1000 -g app app

COPY requirements.txt .
RUN pip install --no-cache-dir --index-url https://nexus.simple-env.site/repository/pypi-proxy/simple/ -r requirements.txt

COPY . .

USER app

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Проверка локально​

# Собрать образ
docker build -t my-backend ./backend

# Проверить что запускается не от root
docker run --rm my-backend whoami
# Должно вывести: app (не root)

# Запустить и проверить
docker run --rm -p 8000:8000 my-backend
curl http://localhost:8000/api/health/