bolt Valebyte VPS від $4/міс — NVMe, запуск за 60 секунд.

Отримати VPS arrow_forward
eco Початковий Туторіал

Розгортання Caddy як

calendar_month Aug 07, 2026 schedule 22 хв. читання visibility 19 переглядів
Развёртывание Caddy как обратного прокси для Docker-контейнеров на VPS с автоматическим HTTPS
info

Потрібен сервер для цього гайду? Ми пропонуємо виділені сервери та VPS у 50+ країнах з миттєвим налаштуванням.

Потрібен сервер для цього гайду?

Розгорніть VPS або виділений сервер за хвилини.

Розгортання Caddy як зворотного проксі для Docker-контейнерів на VPS з автоматичним HTTPS

TL;DR

У цьому детальному посібнику ми налаштуємо Caddy як високоефективний зворотний проксі-сервер для ваших Docker-контейнерів на віртуальному приватному сервері (VPS), забезпечивши автоматичне отримання та оновлення SSL/TLS-сертифікатів через Let's Encrypt. Ви дізнаєтеся, як розгорнути та зв'язати між собою Docker, Docker Compose і Caddy для забезпечення безпечного та масштабованого доступу до ваших веб-додатків, що працюють у контейнерах, з мінімальними зусиллями з конфігурування.

  • Встановлення та базове налаштування операційної системи (Ubuntu 24.04/26.04 LTS).
  • Розгортання Docker та Docker Compose для керування контейнерами.
  • Встановлення та налаштування Caddy як зворотного проксі.
  • Конфігурація Caddy для автоматичної видачі HTTPS-сертифікатів.
  • Приклад розгортання програми в Docker та її проксіювання через Caddy.
  • Рекомендації щодо безпеки, резервного копіювання та обслуговування системи.

Що ми налаштовуємо і навіщо

Схема: Що ми налаштовуємо і навіщо
Схема: Що ми налаштовуємо і навіщо

У цьому посібнику ми займемося створенням надійної та безпечної інфраструктури для хостингу веб-додатків на власному VPS. Основне завдання — забезпечити доступ до додатків, що працюють всередині Docker-контейнерів, ззовні через доменне ім'я, при цьому автоматично захистивши з'єднання за допомогою HTTPS. Для цього ми використовуємо зв'язку з трьох ключових компонентів:

  • Docker: Платформа для контейнеризації додатків. Docker дозволяє упаковувати додатки з усіма їхніми залежностями в ізольовані "контейнери", що забезпечує їхню переносимість та передбачуваність роботи в будь-якому середовищі. Ми будемо використовувати Docker Compose для оркестрації кількох контейнерів, що складають один додаток або сервіс.
  • Caddy: Сучасний веб-сервер та зворотний проксі. Caddy виділяється своєю простотою конфігурації і, що найголовніше, вбудованою підтримкою автоматичної видачі та оновлення SSL/TLS-сертифікатів через Let's Encrypt. Це позбавляє від необхідності вручну налаштовувати Certbot або інші інструменти для HTTPS, значно спрощуючи процес.
  • VPS (Virtual Private Server): Віртуальний приватний сервер, який надасть нам необхідну обчислювальну потужність та мережеві ресурси для розміщення нашої інфраструктури.

У підсумку, читач отримає повністю налаштовану систему, здатну безпечно та ефективно розміщувати один або кілька веб-додатків (наприклад, GitLab, Mattermost, WordPress, або кастомні SaaS-додатки) у Docker-контейнерах, доступних за доменними іменами з автоматичним HTTPS. Це ідеальне рішення для розробників, стартапів та ентузіастів, які бажають мати повний контроль над своєю інфраструктурою без високих витрат на хмарні managed-сервіси.

Альтернативи: Cloud-managed vs. Self-hosted на VPS

Існує два основні підходи до розгортання веб-додатків:

  • Cloud-managed сервіси: Такі платформи, як Heroku, Netlify, AWS Elastic Beanstalk, Google App Engine, пропонують високу автоматизацію, масштабованість та мінімальні зусилля з адміністрування. Ви просто завантажуєте свій код, а платформа дбає про сервери, масштабування, бази даних та HTTPS.
    Переваги: Простота, висока доступність, автоматичне масштабування.
    Недоліки: Висока вартість при зростанні, менший контроль над інфраструктурою, прив'язка до конкретного провайдера, іноді обмежені можливості кастомізації.
  • Self-hosted на VPS/Dedicated сервері: Цей підхід передбачає оренду "голого" сервера (віртуального або фізичного) та самостійне налаштування всього стеку — операційної системи, веб-сервера, бази даних, контейнеризації тощо.
    Переваги: Повний контроль над кожним аспектом системи, значно нижча вартість у довгостроковій перспективі (особливо при помірних навантаженнях), гнучкість у виборі технологій та конфігурацій, конфіденційність даних.
    Недоліки: Вимагає технічних знань та часу на налаштування й обслуговування, відповідальність за безпеку та резервне копіювання лежить на вас.

Вибір self-hosted на VPS з Caddy та Docker є золотою серединою для тих, хто шукає баланс між контролем, вартістю та простотою використання. Caddy значно знижує бар'єр входу для самостійного налаштування HTTPS, а Docker спрощує керування додатками.

Який VPS-конфіг потрібен для цього завдання

Схема: Який VPS-конфіг потрібен для цього завдання
Схема: Який VPS-конфіг потрібен для цього завдання

Вибір відповідного VPS-конфігу критичний для стабільної роботи ваших додатків. Вимоги залежатимуть від кількості та ресурсоємності Docker-контейнерів, які ви плануєте запускати.

Мінімальні вимоги для базової установки (Caddy + 1-2 легких контейнера)

  • CPU: 1-2 ядра (наприклад, Intel Xeon E3/E5 або AMD EPYC). Для більшості веб-додатків одного ядра достатньо, але два дадуть запас продуктивності та кращу чуйність.
  • RAM: 2 ГБ. Docker та Caddy самі по собі споживають небагато, але кожен додаток у контейнері вимагає своєї пам'яті. 2 ГБ — це комфортний мінімум для ОС, Docker-демона та пари невимогливих сервісів (наприклад, невеликий блог на WordPress без важкої СУБД або простий API-сервіс).
  • Диск: 40-60 ГБ NVMe SSD. SSD значно прискорює операції введення-виведення, що важливо для баз даних та швидкого запуску контейнерів. NVMe пропонує ще більшу швидкість. 40-60 ГБ достатньо для ОС, Docker-образів, контейнерів та невеликого обсягу даних. Якщо плануються великі обсяги даних (наприклад, файлові сховища, логи, резервні копії), знадобиться більше місця.
  • Мережа: 100-200 Мбіт/с. Для більшості завдань цього більш ніж достатньо. Важливіша стабільність каналу та низька затримка.

Конкретний VPS-план для завдання

Для розгортання Caddy з 3-5 Docker-контейнерами (наприклад, GitLab, Mattermost або кілька мікросервісів) рекомендується наступний конфігураційний план:

  • CPU: 2-4 ядра (наприклад, Intel Xeon E5-2690v4 або AMD EPYC 7002 series). Це забезпечить достатню продуктивність для обробки запитів та фонових завдань контейнерів.
  • RAM: 4-8 ГБ. Для більш вимогливих додатків, таких як GitLab, Mattermost або Minecraft-сервер, 4 ГБ — це мінімум, 8 ГБ дадуть значно більше свободи та стабільності.
  • Диск: 80-160 ГБ NVMe SSD. GitLab, Minecraft та інші подібні додатки можуть займати значне місце на диску. NVMe SSD забезпечить високу швидкість роботи з даними.
  • Мережа: 500 Мбіт/с - 1 Гбіт/с. Висока пропускна здатність буде корисна для додатків з великою кількістю користувачів або інтенсивним трафіком.

Можна розглянути VPS із зазначеними характеристиками, щоб отримати оптимальне співвідношення ціни та продуктивності для такого завдання. Переконайтеся, що обраний план включає публічну IPv4-адресу, яка необхідна для доступу до ваших сервісів з інтернету та роботи Let's Encrypt.

Коли потрібен dedicated, а не VPS

Виділений сервер (dedicated server) стає кращим вибором, коли:

  • Висока продуктивність та стабільність: Потрібна максимальна та передбачувана продуктивність без "шумних сусідів" на одному фізичному сервері.
  • Великі обсяги даних: Планується зберігання сотень гігабайт або терабайт даних.
  • Складні обчислення: Потрібні спеціалізовані процесори (наприклад, GPU для машинного навчання) або дуже велика кількість ядер.
  • Суворі вимоги до безпеки/комплаєнсу: Необхідний повний фізичний контроль над обладнанням.
  • Масштабний трафік: Очікується дуже високий мережевий трафік (десятки ТБ на місяць).

Для більшості завдань, описаних у цьому посібнику (GitLab для команди, Mattermost, Minecraft для друзів), потужний VPS буде достатнім. Однак, якщо ви запускаєте великий SaaS-проект з тисячами користувачів або високонавантажену криптоноду, розгляньте відповідний dedicated сервер.

Локація: на що впливає

Вибір локації VPS має кілька ключових аспектів:

  • Затримка (Latency): Чим ближче сервер до вашої основної аудиторії, тим нижчою буде затримка і швидше завантажуватимуться сторінки для кінцевих користувачів. Для європейської аудиторії вибирайте сервер у Європі, для американської — у Північній Америці.
  • Регуляторні вимоги: У деяких юрисдикціях існують суворі закони щодо зберігання даних (наприклад, GDPR в ЄС). Вибір локації сервера може впливати на відповідність цим вимогам.
  • Вартість: Ціни на VPS можуть незначно відрізнятися залежно від регіону.

Для більшості завдань, якщо ваша аудиторія розподілена, вибирайте локацію, яка знаходиться географічно близько до вас або до вашої основної групи користувачів.

Підготовка сервера

Схема: Підготовка сервера
Схема: Підготовка сервера

Після отримання доступу до вашого нового VPS необхідно виконати низку початкових налаштувань для забезпечення безпеки та зручності роботи. Ми будемо використовувати Ubuntu Server 24.04/26.04 LTS як операційну систему.

Передбачається, що ви отримали доступ до сервера по SSH під користувачем root або іншим користувачем з правами sudo.

1. Оновлення системи

Насамперед оновимо всі пакети до актуальних версій.


sudo apt update          # Оновлюємо списки доступних пакетів
sudo apt upgrade -y      # Оновлюємо всі встановлені пакети
sudo apt autoremove -y   # Видаляємо непотрібні пакети

2. Створення нового користувача з правами sudo (якщо ви працюєте під root)

Робота під користувачем root небезпечна. Створимо нового користувача та надамо йому права sudo.


sudo adduser username    # Замініть 'username' на бажане ім'я користувача. Дотримуйтесь інструкцій для створення пароля.
sudo usermod -aG sudo username # Додаємо користувача до групи sudo для отримання прав адміністратора.

Тепер вийдіть з поточної SSH-сесії (exit) та увійдіть під новим користувачем:


ssh username@your_vps_ip # Замініть 'username' та 'your_vps_ip'

3. Налаштування SSH-ключів для безпечного доступу

Використання SSH-ключів набагато безпечніше, ніж паролів. Якщо у вас ще немає SSH-ключа, згенеруйте його на вашій локальній машині:


ssh-keygen -t ed25519 -C "[email protected]" # Створюємо новий SSH-ключ (ed25519 безпечніший)

Потім скопіюйте публічний ключ на ваш VPS:


ssh-copy-id username@your_vps_ip # Копіюємо публічний ключ на сервер

Тепер ви можете входити на сервер без пароля. Після перевірки роботи SSH-ключів рекомендується відключити вхід за паролем для root та вашого нового користувача, а також заборонити вхід для root.


sudo nano /etc/ssh/sshd_config # Відкриваємо конфігураційний файл SSH-сервера

Знайдіть та змініть наступні рядки:


PermitRootLogin no
PasswordAuthentication no

Збережіть зміни (Ctrl+X, Y, Enter) та перезапустіть SSH-сервер:


sudo systemctl restart sshd # Перезапускаємо службу SSH

Важливо: Переконайтеся, що ви можете увійти за SSH-ключем, перш ніж відключати вхід за паролем! Інакше ви можете втратити доступ до сервера.

4. Встановлення та налаштування міжмережевого екрана (UFW)

UFW (Uncomplicated Firewall) — це простий у використанні інтерфейс для налаштування iptables. Він необхідний для обмеження доступу до сервера лише за необхідними портами.


sudo apt install ufw -y # Встановлюємо UFW
sudo ufw allow OpenSSH  # Дозволяємо SSH (порт 22)
sudo ufw allow http     # Дозволяємо HTTP (порт 80)
sudo ufw allow https    # Дозволяємо HTTPS (порт 443)
sudo ufw enable         # Вмикаємо UFW. Підтвердіть 'y'.
sudo ufw status verbose # Перевіряємо статус UFW

5. Встановлення Fail2ban для захисту від брутфорсу

Fail2ban сканує логи сервісів (SSH, веб-серверів тощо) на предмет підозрілої активності (наприклад, багаторазові невдалі спроби входу) та тимчасово або перманентно блокує IP-адреси зловмисників за допомогою правил фаєрволу.


sudo apt install fail2ban -y # Встановлюємо Fail2ban
sudo systemctl enable fail2ban # Вмикаємо автозапуск Fail2ban під час завантаження
sudo systemctl start fail2ban  # Запускаємо службу Fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Створюємо локальну копію конфігурації для змін
sudo nano /etc/fail2ban/jail.local # Редагуємо конфігурацію

У файлі jail.local ви можете налаштувати параметри, такі як bantime (час блокування), findtime (період, протягом якого враховуються невдалі спроби) та maxretry (максимальна кількість спроб). Переконайтеся, що секція [sshd] увімкнена (enabled = true). Можете збільшити bantime, наприклад, до 1h або навіть 1d.


[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

Збережіть зміни та перезапустіть Fail2ban:


sudo systemctl restart fail2ban # Перезапускаємо Fail2ban для застосування змін
sudo fail2ban-client status sshd # Перевіряємо статус захисту SSH

Встановлення ПЗ — покроково

Схема: Встановлення ПЗ — покроково
Схема: Встановлення ПЗ — покроково

Тепер, коли сервер підготовлений, перейдемо до встановлення основного програмного забезпечення: Docker, Docker Compose та Caddy.

1. Встановлення Docker Engine (актуально на 2026 рік)

Ми будемо встановлювати Docker з офіційного репозиторію Docker, щоб завжди мати актуальні версії. Актуальні версії Docker Engine на 2026 рік будуть, ймовірно, в діапазоні 25.x-26.x.


# Оновлюємо пакети та встановлюємо залежності
sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release

# Додаємо офіційний GPG ключ Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Додаємо репозиторій Docker до джерел APT
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Оновлюємо списки пакетів з новим репозиторієм
sudo apt update

# Встановлюємо Docker Engine, Docker CLI та containerd
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Додаємо поточного користувача до групи docker для роботи без sudo
sudo usermod -aG docker "$USER"

# Застосовуємо зміни для групи Docker (потрібно перелогінитися або перезавантажити)
# Але краще просто перелогінитися або виконати 'newgrp docker'
newgrp docker

# Перевіряємо встановлення Docker
docker run hello-world

Команда docker run hello-world повинна успішно завантажити та запустити тестовий контейнер, підтверджуючи коректне встановлення Docker.

2. Встановлення Docker Compose

Docker Compose — це інструмент для визначення та запуску багатоконтейнерних Docker-додатків. Він постачається як частина Docker Engine з версії 2.x.


# Перевіряємо версію Docker Compose (Docker Compose v2.x постачається як плагін Docker CLI)
docker compose version

Якщо команда docker compose version повертає помилку або дуже стару версію, можливо, вам знадобиться встановити його окремо. Однак, для Ubuntu 24.04/26.04 та Docker Engine 25.x+ він має бути доступний за замовчуванням.

3. Встановлення Caddy (актуально на 2026 рік)

Caddy можна встановити з офіційного репозиторію Caddy, що гарантує отримання останніх стабільних версій (Caddy 2.x).


# Встановлюємо залежності для додавання репозиторію HTTPS
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https

# Додаємо GPG ключ Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

# Додаємо репозиторій Caddy до джерел APT
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

# Оновлюємо списки пакетів з новим репозиторієм
sudo apt update

# Встановлюємо Caddy
sudo apt install -y caddy

# Перевіряємо статус служби Caddy
sudo systemctl status caddy

Служба Caddy має бути встановлена та запущена. Якщо вона не запущена, запустіть її: sudo systemctl start caddy.

Конфігурація

Схема: Конфігурація
Схема: Конфігурація

Тепер, коли всі компоненти встановлені, настав час налаштувати їхню взаємодію. Ми налаштуємо Caddy як зворотний проксі для Docker-контейнерів, використовуючи Docker Compose для визначення наших застосунків.

1. Підготовка мережевої інфраструктури Docker

Для того щоб Caddy міг взаємодіяти з вашими Docker-контейнерами за їхніми внутрішніми іменами, їх потрібно помістити в одну користувацьку мережу Docker.


# Створюємо користувацьку мережу Docker для Caddy та застосунків
docker network create caddy_network

Цю мережу ми будемо вказувати у файлах docker-compose.yml для наших застосунків та для самого Caddy.

2. Конфігурація Caddyfile

Caddy використовує файл Caddyfile для своєї конфігурації. Ми налаштуємо його для проксіювання трафіку до наших Docker-контейнерів.


sudo nano /etc/caddy/Caddyfile # Відкриваємо основний конфігураційний файл Caddy

Видаліть існуючий вміст і вставте наступне. Замініть your-app.example.com та another-app.example.com на ваші реальні доменні імена, а app_container_name та another_app_container_name на імена ваших Docker-контейнерів.


# Глобальні налаштування Caddy
{
    # Вказуємо, що Caddy повинен використовувати DNS-сервери Google для Let's Encrypt
    # Це може бути корисно, якщо у вашого VPS є проблеми з розпізнаванням DNS
    # acme_dns google # Розкоментуйте, якщо використовуєте DNS-провайдера, що підтримує ACME DNS challenge
    # email [email protected] # Вкажіть ваш email для сповіщень Let's Encrypt
}

# Конфігурація для першого застосунку
your-app.example.com {
    # Проксіюємо весь трафік на Docker-контейнер
    reverse_proxy app_container_name:80

    # Додаткові заголовки для кращої сумісності та безпеки
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options DENY
        X-Content-Type-Options nosniff
        X-XSS-Protection "1; mode=block"
    }

    # Логування запитів
    log {
        output file /var/log/caddy/your-app.log
        format json
    }

    # Стиснення Gzip (опціонально, але рекомендується)
    encode gzip
}

# Конфігурація для другого застосунку (приклад)
another-app.example.com {
    reverse_proxy another_app_container_name:8080 # Вкажіть порт, на якому слухає ваш другий застосунок

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options DENY
        X-Content-Type-Options nosniff
        X-XSS-Protection "1; mode=block"
    }

    log {
        output file /var/log/caddy/another-app.log
        format json
    }

    encode gzip
}

# Ви також можете додати директиву для статичних файлів, якщо Caddy буде їх обслуговувати
# example.com {
#     root  /var/www/html
#     file_server
# }

Пояснення до Caddyfile:

  • your-app.example.com: Це доменне ім'я, за яким буде доступний ваш застосунок. Caddy автоматично отримає для нього HTTPS-сертифікат. Переконайтеся, що DNS-запис (A-запис) для цього домену вказує на IP-адресу вашого VPS.
  • reverse_proxy app_container_name:80: Caddy перенаправлятиме всі вхідні запити на внутрішню IP-адресу Docker-контейнера з ім'ям app_container_name на порту 80 (або іншому, на якому слухає ваш застосунок всередині контейнера). Важливо, що app_container_name — це ім'я сервісу у вашому файлі docker-compose.yml.
  • header: Додає HTTP-заголовки для підвищення безпеки.
  • log: Налаштовує логування запитів. Переконайтеся, що директорія /var/log/caddy/ існує і Caddy має до неї права.
  • encode gzip: Вмикає стиснення Gzip для переданих даних.

Створимо директорію для логів Caddy:


sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddy # Надаємо права користувачу caddy
sudo systemctl restart caddy # Перезапускаємо Caddy для застосування нового Caddyfile
sudo systemctl status caddy  # Перевіряємо, що Caddy успішно запустився

3. Приклад розгортання застосунку з Docker Compose

Давайте створимо приклад простого веб-застосунку (наприклад, Nginx з тестовою сторінкою), який буде доступний через Caddy.


mkdir ~/my_web_app
cd ~/my_web_app
nano docker-compose.yml

Вміст docker-compose.yml:


version: '3.8'

services:
  # Ім'я сервісу, яке використовуватиме Caddy для проксіювання
  # Переконайтеся, що воно збігається з ім'ям у Caddyfile (наприклад, 'app_container_name')
  mywebapp:
    image: nginx:latest # Використовуємо актуальний образ Nginx
    container_name: mywebapp_container # Явне ім'я контейнера
    restart: unless-stopped
    ports:
      - "80" # Nginx слухає на порту 80 всередині контейнера
    networks:
      - caddy_network # Підключаємо контейнер до мережі Caddy

networks:
  caddy_network:
    external: true # Вказуємо, що мережа вже існує і була створена вручну

Збережіть файл (Ctrl+X, Y, Enter) і запустіть застосунок:


docker compose up -d # Запускаємо контейнер у фоновому режимі

Тепер відредагуйте ваш Caddyfile, щоб він проксіював на mywebapp:


sudo nano /etc/caddy/Caddyfile

Додайте або змініть секцію для вашого домену:


# ... інші налаштування ...

# Конфігурація для вашого нового застосунку
my-nginx-app.example.com { # Замініть на ваш реальний домен
    reverse_proxy mywebapp:80 # Ім'я сервісу з docker-compose.yml та внутрішній порт
    log {
        output file /var/log/caddy/my-nginx-app.log
        format json
    }
    encode gzip
}

# ... інші налаштування ...

Перезапустіть Caddy:


sudo systemctl reload caddy # Перезавантажуємо конфігурацію Caddy без зупинки сервісу

Переконайтеся, що DNS-запис для my-nginx-app.example.com вказує на IP-адресу вашого VPS. Через кілька секунд (або хвилин, поки Caddy отримає сертифікат) ваш застосунок має бути доступний за HTTPS.

4. Налаштування змінних оточення (.env) для секретів

Ніколи не зберігайте конфіденційні дані (паролі, API-ключі) безпосередньо в docker-compose.yml. Використовуйте змінні оточення через файл .env.

Створіть файл .env у тій самій директорії, що й docker-compose.yml:


nano ~/my_web_app/.env

Приклад вмісту .env:


DB_PASSWORD=MyStrongPassword123
API_KEY=supersecretkeyabc123

Потім у docker-compose.yml ви можете посилатися на ці змінні:


version: '3.8'

services:
  mywebapp:
    image: mycustomapp:latest
    container_name: mywebapp_container
    restart: unless-stopped
    environment:
      - DB_PASSWORD=${DB_PASSWORD} # Передаємо змінну з .env
      - API_KEY=${API_KEY}
    networks:
      - caddy_network

networks:
  caddy_network:
    external: true

При запуску docker compose up -d Docker Compose автоматично підставить значення з .env.

5. Перевірка працездатності

Після всіх налаштувань необхідно переконатися, що все працює коректно.

  • Перевірка Caddy:
    
    sudo systemctl status caddy # Переконайтеся, що Caddy працює
    sudo journalctl -u caddy --since "10 minutes ago" # Перевірте логи Caddy на наявність помилок
    
  • Перевірка Docker-контейнерів:
    
    docker ps # Переконайтеся, що ваші контейнери запущені
    docker logs mywebapp_container # Перевірте логи конкретного контейнера
    
  • Перевірка доступності через домен:

    На вашій локальній машині використовуйте curl для перевірки HTTPS-з'єднання:

    
    curl -vI https://my-nginx-app.example.com # Перевіряємо заголовки HTTP та статус SSL-сертифіката
    

    Ви повинні побачити статус HTTP/2 200 та інформацію про SSL-сертифікат, виданий Let's Encrypt. Якщо є проблеми, переконайтеся, що DNS-запис коректний і порти 80/443 відкриті в UFW.

Резервне копіювання та обслуговування

Схема: Резервне копіювання та обслуговування
Схема: Резервне копіювання та обслуговування

Регулярне резервне копіювання та своєчасне обслуговування сервера є критично важливими для стабільності та безпеки вашої інфраструктури.

1. Що резервувати

Для Docker-контейнерів та Caddy необхідно резервувати наступні дані:

  • Docker Volumes: Це найважливіша частина. Усі постійні дані ваших застосунків (бази даних, завантажені файли, дані користувачів) повинні зберігатися в Docker Volumes. Переконайтеся, що ви правильно мапуєте їх з контейнерів на хостову систему.
  • Конфігураційні файли Caddy: Файл /etc/caddy/Caddyfile та будь-які інші файли, на які він посилається.
  • Конфігураційні файли Docker Compose: Файли docker-compose.yml для всіх ваших застосунків.
  • SSL-сертифікати Caddy: Caddy зберігає свої сертифікати у /var/lib/caddy/.local/share/caddy/. Хоча Caddy автоматично їх відновить, резервна копія може прискорити відновлення.
  • Системні конфігурації: SSH-конфігурація, правила UFW, налаштування Fail2ban.

2. Простий скрипт авторезервування

Ми створимо простий скрипт, який буде архівувати важливі дані та відправляти їх у безпечне місце. Для прикладу будемо використовувати tar для архівації та rsync для копіювання на віддалений сервер. Для більш надійних та інкрементальних резервних копій розгляньте restic або borgbackup.

Створіть директорію для скриптів і сам скрипт:


mkdir -p ~/scripts
nano ~/scripts/backup_script.sh

Вміст backup_script.sh (замініть /path/to/your/docker_volumes та user@remote_backup_server:/path/to/backups на ваші значення):


#!/bin/bash

# Налаштування
BACKUP_DIR="/var/backups/my_vps"
DATA_TO_BACKUP="/path/to/your/docker_volumes /etc/caddy /etc/ssh /etc/ufw /etc/fail2ban /home/username/my_web_app"
REMOTE_BACKUP_TARGET="user@remote_backup_server:/path/to/backups" # S3-сумісне сховище або інший VPS

# Створюємо директорію для резервних копій, якщо її немає
mkdir -p "$BACKUP_DIR"

# Ім'я файлу резервної копії
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILENAME="vps_backup_${TIMESTAMP}.tar.gz"
FULL_BACKUP_PATH="${BACKUP_DIR}/${BACKUP_FILENAME}"

echo "Запуск резервного копіювання о ${TIMESTAMP}..."

# Створюємо архів
sudo tar -czf "$FULL_BACKUP_PATH" $DATA_TO_BACKUP

if [ $? -eq 0 ]; then
    echo "Архів резервної копії створено: $FULL_BACKUP_PATH"
    # Копіюємо архів на віддалений сервер
    rsync -avz --remove-source-files "$FULL_BACKUP_PATH" "$REMOTE_BACKUP_TARGET"

    if [ $? -eq 0 ]; then
        echo "Резервну копію успішно передано на віддалений сервер: $REMOTE_BACKUP_TARGET"
        # Очищення старих резервних копій (наприклад, зберігаємо 7 останніх)
        find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +7 -delete
        echo "Старі локальні резервні копії очищено."
    else
        echo "ПОМИЛКА: Не вдалося передати резервну копію на віддалений сервер."
    fi
else
    echo "ПОМИЛКА: Не вдалося створити архів резервної копії."
fi

echo "Процес резервного копіювання завершено."

Зробіть скрипт виконуваним:


chmod +x ~/scripts/backup_script.sh

Налаштуйте cron для автоматичного запуску скрипта (наприклад, щодня о 3:00 ночі):


crontab -e # Відкриваємо crontab для поточного користувача

Додайте рядок в кінець файлу:


0 3 * * * /home/username/scripts/backup_script.sh >> /var/log/backup.log 2>&1

Це запускатиме скрипт щодня о 3:00 ранку та записуватиме вивід у /var/log/backup.log.

3. Куди зберігати резервні копії

Ніколи не зберігайте резервні копії на тому ж сервері, що й вихідні дані. Це критично важливо. Варіанти:

  • Зовнішнє S3-сумісне сховище: Хмарні сховища, такі як Amazon S3, DigitalOcean Spaces, Backblaze B2, Yandex Object Storage, пропонують надійне та економічне зберігання. Інструменти на кшталт rclone або restic можуть безпосередньо працювати з S3.
  • Окремий VPS: Недорогий VPS з великим диском, що використовується виключно для зберігання резервних копій. Доступ по SSH/SCP/RSync.
  • Локальне сховище: Якщо це домашній сервер, можна використовувати мережеве сховище (NAS).

4. Оновлення: Rolling vs. Maintenance Window

Підтримання ПЗ в актуальному стані важливе для безпеки та продуктивності.

  • Rolling Updates (безперервні оновлення): Підходить для систем з високою доступністю, де є кілька екземплярів застосунку. Оновлення відбувається по черзі, без зупинки всього сервісу. Для одного VPS це зазвичай не застосовується.
  • Maintenance Window (вікно обслуговування): Стандартний підхід для одиночних серверів. Вибирається час (зазвичай вночі або у вихідні), коли навантаження мінімальна, і проводяться оновлення.
    1. Оновлення ОС: Щомісяця або раз на кілька місяців:
      
      sudo apt update && sudo apt upgrade -y
      sudo reboot # Перезавантаження після оновлення ядра або важливих системних компонентів
                          
    2. Оновлення Docker-образів: Раз на кілька тижнів або по мірі виходу нових версій ваших застосунків:
      
      cd ~/my_web_app # Перейдіть до директорії з docker-compose.yml
      docker compose pull # Завантажуємо нові версії образів
      docker compose up -d # Перестворюємо контейнери з новими образами
                          
    3. Оновлення Caddy: Caddy оновлюється разом із системними пакетами (sudo apt upgrade). Після оновлення Caddy завжди перевіряйте його статус та логи.

Завжди робіть резервну копію перед великими оновленнями або змінами конфігурації.

Troubleshooting + FAQ

У цьому розділі зібрано типові проблеми та поширені запитання, які можуть виникнути при розгортанні Caddy та Docker.

Що робити, якщо Caddy не запускається або не отримує сертифікат?

Проблема: Caddy не запускається, або ви отримуєте помилку "TLS handshake error" / "certificate provisioning failed".

Що перевірити:

  1. Логи Caddy: Це перше, що потрібно перевірити.
    
    sudo journalctl -u caddy --since "5 minutes ago"
                
    Шукайте помилки, пов'язані із синтаксисом Caddyfile або проблемами з Let's Encrypt.
  2. DNS-записи: Переконайтеся, що A-запис вашого домену (наприклад, my-nginx-app.example.com) вказує на публічну IP-адресу вашого VPS. Перевірити можна за допомогою dig або nslookup:
    
    dig +short my-nginx-app.example.com
                
  3. Відкриті порти: Переконайтеся, що порти 80 (HTTP) та 443 (HTTPS) відкриті у вашому фаєрволі (UFW) на VPS. Let's Encrypt використовує порт 80 для HTTP-01 challenge.
    
    sudo ufw status verbose
                
  4. Синтаксис Caddyfile: Використовуйте команду для перевірки синтаксису Caddyfile:
    
    sudo caddy validate --config /etc/caddy/Caddyfile
                
  5. Зайняті порти: Переконайтеся, що жоден інший процес не слухає на портах 80 або 443.
    
    sudo lsof -i :80
    sudo lsof -i :443
                

Як виправити: Виправте DNS-запис, відкрийте порти в UFW, виправте синтаксис Caddyfile згідно з логами. Якщо Let's Encrypt видає помилку про перевищення лімітів, зачекайте деякий час (зазвичай годину) і спробуйте знову.

Контейнер Docker не запускається або недоступний через Caddy.

Проблема: Контейнер не стартує, або Caddy не може до нього достукатися (помилка 502 Bad Gateway).

Що перевірити:

  1. Статус контейнера:
    
    docker ps -a # Показує всі контейнери (запущені та зупинені)
                
    Якщо контейнер не запущений, перевірте його логи:
    
    docker logs mywebapp_container
                
    Шукайте помилки, які можуть вказувати на проблеми із застосунком всередині контейнера.
  2. Мережа Docker: Переконайтеся, що контейнер і Caddy знаходяться в одній мережі Docker (caddy_network).
    
    docker network inspect caddy_network
                
    Шукайте ваш контейнер та контейнер Caddy у списку Containers.
  3. Ім'я сервісу та порт: Переконайтеся, що ім'я сервісу в Caddyfile (наприклад, mywebapp) точно збігається з ім'ям сервісу в docker-compose.yml, і що вказаний порт (наприклад, :80) відповідає порту, на якому застосунок слухає всередині контейнера.

Як виправити: Виправте помилки в docker-compose.yml, перезапустіть контейнер. Перевірте, що ім'я сервісу та порт у Caddyfile коректні та перезавантажте Caddy.

Який VPS-конфіг мінімально підійде?

Для Caddy та одного-двох легких Docker-контейнерів (наприклад, персональний блог, невеликий API) мінімально підійде VPS з 1 CPU ядром, 2 ГБ RAM та 40-60 ГБ NVMe SSD диска. Цього достатньо для стабільної роботи базових сервісів, але при зростанні навантаження або додаванні більш ресурсоємних застосунків (наприклад, баз даних, ігрових серверів) знадобиться апгрейд.

Що вибрати — VPS чи dedicated для цього завдання?

Для більшості завдань, пов'язаних з розгортанням Caddy та Docker-контейнерів (особисті проєкти, невеликі команди, тестові середовища), VPS є оптимальним вибором через свою гнучкість, масштабованість та низьку вартість. Виділений сервер (dedicated) стає виправданим, якщо вам потрібна максимальна та передбачувана продуктивність, дуже великі обсяги дискового простору, специфічне апаратне забезпечення (наприклад, GPU) або суворі вимоги до ізоляції та комплаєнсу. Почніть з VPS і розгляньте перехід на dedicated при значному зростанні вимог.

Як оновити Docker або Caddy?

Для оновлення Docker та Caddy, встановлених з офіційних репозиторіїв, використовуйте стандартні команди менеджера пакетів:


sudo apt update          # Оновлюємо списки пакетів
sudo apt upgrade -y      # Оновлюємо всі встановлені пакети, включно з Docker та Caddy
sudo systemctl restart docker # Перезапускаємо Docker після оновлення
sudo systemctl restart caddy  # Перезапускаємо Caddy після оновлення

Рекомендується виконувати ці дії у "вікно обслуговування" та попередньо створювати резервні копії.

Чи можу я використовувати Caddy для кількох доменів?

Так, Caddy чудово підходить для хостингу багатьох доменів на одному VPS. Просто додайте нові блоки конфігурації у ваш Caddyfile для кожного домену, вказуючи, на який Docker-контейнер потрібно проксіювати трафік. Caddy автоматично подбає про видачу HTTPS-сертифікатів для всіх зазначених доменів. Не забудьте оновити DNS-записи для кожного нового домену, щоб вони вказували на ваш VPS.


# ...
your-first-app.example.com {
    reverse_proxy first_app_container:80
}

your-second-app.example.com {
    reverse_proxy second_app_container:8080
}
# ...

Як додати базову автентифікацію (логін/пароль) через Caddy?

Caddy підтримує базову HTTP-автентифікацію. Ви можете додати її до блоку вашого домену в Caddyfile:


my-protected-app.example.com {
    reverse_proxy protected_app_container:80
    basicauth / {
        username JDUyJDEwJEQ1R015VjR2bVluYmF1Wk9kSjF4dC5tT1I0L2d6LzZqRTlRSDh3c3B0ZlJ1c05xV0o0NEdwYQ== # Пароль 'SecurePassword123'
    }
}

Замініть username та хеш пароля на свої. Хеш можна згенерувати командою caddy hash-password --plaintext "Your_Secure_Password". Це корисно для захисту внутрішніх інструментів або адмінок.

Висновки та наступні кроки

Схема: Висновки та наступні кроки
Схема: Висновки та наступні кроки

Ми успішно розгорнули Caddy як зворотний проксі для Docker-контейнерів на VPS, забезпечивши автоматичне отримання HTTPS-сертифікатів. Це налаштування надає потужну, гнучку та безпечну основу для хостингу ваших веб-застосунків, поєднуючи простоту Caddy з ізоляцією та переносимістю Docker.

Тепер ви маєте повний контроль над своєю інфраструктурою і можете з легкістю додавати нові застосунки, оновлювати наявні та забезпечувати їх безпеку. Це чудова відправна точка для будь-кого, хто хоче самостійно керувати своїми онлайн-сервісами.

Наступні кроки для розвитку вашої інфраструктури:

  • Моніторинг та логування: Інтегруйте системи моніторингу (наприклад, Prometheus + Grafana) для відстеження стану сервера та контейнерів. Налаштуйте централізоване логування (наприклад, ELK Stack або Loki + Grafana) для ефективного аналізу логів усіх ваших застосунків.
  • CI/CD пайплайни: Автоматизуйте розгортання ваших застосунків за допомогою CI/CD систем (наприклад, GitLab CI, GitHub Actions, Jenkins). Це дозволить вам швидше та надійніше доставляти новий код у продакшн.
  • Збільшення відмовостійкості та масштабування: Для високонавантажених проєктів розгляньте використання Docker Swarm або Kubernetes для оркестрації контейнерів на кількох VPS, забезпечення високої доступності та горизонтального масштабування.

Чи був цей гайд корисним?

Ваш відгук допомагає нам покращувати гайди.

Share this post:

Надішліть гайд тому, кому він може стати в пригоді.

Telegram VKVK WhatsApp Facebook LinkedIn XX

розгортання caddy як зворотного проксі для docker-контейнерів на vps з автоматичним https
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.