В современной веб-разработке статические сайты (SSG) и одностраничные приложения (SPA) стали золотым стандартом благодаря своей производительности и безопасности. Однако процесс их развертывания часто вызывает вопросы: как правильно собрать фронтенд, настроить веб-сервер и, главное, как автоматизировать получение SSL-сертификатов?
В этой статье мы разберем надежную и современную архитектуру деплоя, объединив три мощных инструмента:Vite(сборщик),Docker(контейнеризация) иCaddy(веб-сервер). Такой стек позволяет забыть о ручной настройке Nginx и мучениях с Certbot, получая на выходе легковесный, безопасный и автоматически обновляемый сайт.
Почему именно этот стек?
Vite:Генерирует чистую статику (HTML, JS, CSS). Для работы сайта в продакшене Node.js не требуется, что критически снижает потребление ресурсов на сервере.
Docker:Позволяет создать изолированное окружение. Мы используеммногоступенчатую сборку(multi-stage build), чтобы в итоговом образе остался только веб-сервер и статика, а не гигабайты node_modules.
Caddy:Это веб-сервер нового поколения, написанный на Go. Его «киллер-фича» — автоматический HTTPS. Caddy сам получает и продлевает сертификаты Let's Encrypt через протокол ACME, требуя от вас лишь указать домен в конфиге.
Шаг 1. Конфигурация Caddy: Безопасность и автоматизация
В отличие от Nginx, конфигурация которого может занимать десятки строк для простого кейса, Caddyfile невероятно лаконичен. Мы настроим автоматическое перенаправление с HTTP на HTTPS, включим сжатие и зададим заголовки безопасности.
Создайте в корне проекта файл Caddyfile:
```
# Домен читается из переменных окружения (.env)
{$DOMAIN} {
# Автоматическая выдача SSL-сертификата на указанную почту
tls {$EMAIL}
# Корневая директория для статики внутри контейнера
# Путь /usr/share/caddy является стандартным для образа Caddy
root * /usr/share/caddy
# Запускаем файловый сервер, который сам определяет MIME-типы
file_server
# Включаем сжатие GZIP для экономии трафика
encode gzip
# Настройка кэширования статических ассетов (картинок, шрифтов, JS/CSS)
# immutable позволяет браузеру не переспрашивать файлы при жестком обновлении
header /assets/* Cache-Control: "public, max-age=31536000, immutable"
header /*.css Cache-Control: "public, max-age=31536000, immutable"
header /*.js Cache-Control: "public, max-age=31536000, immutable"
# Логика маршрутизации для SPA (Single Page Application):
# Если файл не найден, отдаем index.html (нужно для роутинга Vue/React)
try_files {path} {path}/ /index.html