Глава 49. Docker для фронтендера: контейнеры без боли

Зачем эта глава

Docker позволяет запускать проект в одинаковой среде у всех членов команды. Это снижает «у меня работает».

Основная идея

Контейнер — это изолированная среда с твоим приложением.

Пример Dockerfile

Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
Важно: Docker полезен для команд и CI, даже если проект фронтендовый.

Docker Compose и Nginx для статической сборки

Если у тебя фронтенд на Vite/React, после сборки появляется папка dist. Её удобно отдавать через Nginx.

Dockerfile
FROM node:18-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
docker-compose.yml
services:
web:
  build: .
  ports:
    - "8080:80"
Важно: такой подход часто используют на продакшене для статических сайтов.

Nginx reverse‑proxy + .env

В команде удобно проксировать API через Nginx. Тогда фронту достаточно ходить на /api, а Nginx перенаправит запросы.

docker-compose.yml
services:
web:
  build: .
  ports:
    - "8080:80"
  env_file:
    - .env
  depends_on:
    - api

api:
  image: my-backend:latest
  ports:
    - "4000:4000"
nginx.conf
server {
  listen 80;

  location / {
    root /usr/share/nginx/html;
    try_files $uri /index.html;
  }

  location /api/ {
    proxy_pass http://api:4000/;
  }
}
.env
VITE_API_URL=/api
Подсказка: в dev и prod URL часто разные. Используй переменные окружения.

HTTPS через Certbot (реальный продакшен)

Для HTTPS можно использовать бесплатные сертификаты Let’s Encrypt через Certbot. В Docker это обычно делается отдельным контейнером.

docker-compose.yml
services:
nginx:
  image: nginx:alpine
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/conf.d/default.conf
    - ./certbot/www:/var/www/certbot
    - ./certbot/conf:/etc/letsencrypt

certbot:
  image: certbot/certbot
  volumes:
    - ./certbot/www:/var/www/certbot
    - ./certbot/conf:/etc/letsencrypt
  command: certonly --webroot -w /var/www/certbot -d example.com --email you@mail.com --agree-tos --no-eff-email
nginx.conf (SSL)
server {
  listen 80;
  server_name example.com;
  location /.well-known/acme-challenge/ { root /var/www/certbot; }
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name example.com;
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  location / { root /usr/share/nginx/html; try_files $uri /index.html; }
  location /api/ { proxy_pass http://api:4000/; }
}
Важно: сертификаты нужно обновлять (обычно cron‑задачей раз в 60 дней).

Задания

Задание: контейнер

  • Создай Dockerfile.
  • Запусти контейнер локально.
  • Проверь, что проект открывается.