Глава 49. Docker для фронтендера: контейнеры без боли
Зачем эта глава
Docker позволяет запускать проект в одинаковой среде у всех членов команды. Это снижает «у меня работает».
Основная идея
Контейнер — это изолированная среда с твоим приложением.
Пример Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
Важно: Docker полезен для команд и CI, даже если проект фронтендовый.
Dockerfile
docker-compose.yml
docker-compose.yml
nginx.conf
.env
docker-compose.yml
nginx.conf (SSL)
Docker Compose и Nginx для статической сборки
Если у тебя фронтенд на Vite/React, после сборки появляется папка dist. Её удобно отдавать через Nginx.
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
services:
web:
build: .
ports:
- "8080:80"
Важно: такой подход часто используют на продакшене для статических сайтов.
Nginx reverse‑proxy + .env
В команде удобно проксировать API через Nginx. Тогда фронту достаточно ходить на /api, а Nginx перенаправит запросы.
services:
web:
build: .
ports:
- "8080:80"
env_file:
- .env
depends_on:
- api
api:
image: my-backend:latest
ports:
- "4000:4000"
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://api:4000/;
}
}
VITE_API_URL=/api
Подсказка: в dev и prod URL часто разные. Используй переменные окружения.
HTTPS через Certbot (реальный продакшен)
Для HTTPS можно использовать бесплатные сертификаты Let’s Encrypt через Certbot. В Docker это обычно делается отдельным контейнером.
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
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.
- Запусти контейнер локально.
- Проверь, что проект открывается.