главная
фотографии обо мне

8 февраля 2026 г.

Поднимаем Dokku рядом с Caddy

Как удобно совместить Dokku и неDokku-приложения

Мне давно нравится использовать Dokku для развертывания проектов, которые я делаю (см. первую статью про Dokku). При этом очевидно, что с помощью Dokku неудобно разворачивать сторонние сервисы, для этого удобнее использовать простой Docker Compose, а иногда и вообще хочется запустить что-то просто на “голом железе”, без контейнеров.

Вот мы подняли у себя на сервере пару приложений Dokku, пару контейнеров через Docker Compose, и в добавок небольшой сервис запустили прямо из бинарного файла. Теперь к этому всему хочется настроить маршрутизацию запросов, чтобы:

  • запросы к домену blog.example.com шли в Dokku-приложение,
  • запросы к домену stats.example.com шли в обычный Docker-контейнер, который мы подняли через Docker Compose
  • запросы к домену runner.example.com и вовсе шли куда-то на порт, который слушает запущенный из бинарного файла сервис

К сожалению, когда мы настраиваем Dokku по самой простой инструкции, то Dokku забирает себе порты 80 и 443, и работает так, что маршутризировать запросы может только в Dokku-же приложения.

Значит, нам нужно:

  • настроить Dokku так, чтобы он слушал не 80 и не 443 порты
  • перед Dokku поднять сервис, который будет маршрутизировать трафик

Самый простой способ поднять Dokku, как оказалось - поднять его в Docker:

docker container run -d \
--env DOKKU_HOST_ROOT=/var/lib/dokku/home/dokku \
--env DOKKU_LIB_HOST_ROOT=/var/lib/dokku/var/lib/dokku \
--name dokku \
--publish 3022:22 \
--publish 8080:80 \
--publish 8443:443 \
--volume /var/lib/dokku:/mnt/dokku \
--volume /var/run/docker.sock:/var/run/docker.sock \
dokku/dokku:0.37.6

обратите внимание на маппинг портов:

  • 80-ый порт (HTTP) Dokku будет доступен с 8080 порта хоста
  • 443-ый порт (HTTPS) Dokku доступен с 8443 порта хоста
  • 22-ой порт (SSH) Dokku доступен с 3022-ой порта хоста

Настройка таким образом поднятого Dokku совпадает с обычной настройкой, только вместо команды dokku нужно писать docker exec dokku dokku. Например:

$ docker exec dokku dokku apps:create blog

Если вы используете оболочку fish, то можно создать соответсвующий alias:

~> alias dokku="docker exec dokku dokku" --save

это позволит пользоваться привычной командой dokku, fish под капотом сам заменит ее на docker exec dokku dokku.

Небольшая ремарка по настройке: чтобы добавить SSH-ключ админа, нужно будет зайти в командную строку контейнера и выполнить echo "<публичный ключ>" | dokku ssh-keys:add admin. Если выполнить команду с хоста echo "<публичный ключ>" | docker exec dokku dokku ssh-keys:add admin, то ничего не произойдет.

В качестве сервиса для маршрутизации запросов я использую Caddy. Не буду описывать как его поднять, смотрите документацию: https://caddyserver.com/docs/install

Предположим что я хочу направить трафик с домена blog.example.com на приложение blog, которое управляется Dokku. Для этого нужно:

  1. Присвоить домен blog.example.com нашему приложению: docker exec dokku dokku domains:add blog blog.example.com
  2. Добавить правило маршрутизации трафика в Caddyfile:
blog.example.com {
    reverse_proxy 127.0.0.1:8080
}

Благодаря такому подходу, сохраняется и удобство + надежность развертывания приложений через Caddy, а также гибкость и простота запуска сторонних приложений через Docker Compose или вообще без контейнеров. При этом, все запросы к сервисам идут через HTTPS, а маршрутизация настраивается в единой точке.