Управление Docker контейнерами без Portainer и Dockge

Долгое время я сидел на Dockge, оно хостится у меня на малинке. А на самой малинке я гоняю: jellifyn, qbittorrent, grafana, prometheus, uptime kuma, watchyourlan, technitium dns.

 читать первым в телеграм    читать первым в макс

Для таких целей Portainer крайне избыточен, мне в хер не уперся космический корабль, да и многое в Portainer сделано через жопу, хрен чё найдешь.

Поэтому Dockge покрывает все мои хотелки. Но рано или поздно хочется нового.

И новое это — DockHand. Причем этот проект не просто пилит какой-то энтузиаст, проект с закосом на интерпрайз. Но полностью opensource.

Люблю opensource, за то, что если есть закос на интерпрайз, то можно посмотреть исходники и реверснуть лицензию. С DocHand я пока особо глубоко не ковырялся, но чуть позже обязательно пропатчу, как собственно провернул это с mattermost, gitlab и т.п.

Да, по функционалу DocHand ничем не уступает Portainer и даже превосходит его. Для меня важно, чтобы всё было очевидно и понятно, без - хуй чё найдешь. И тут с этим всё прекрасно.

Ладно, чем бы дитя не тешилось. Вкорячиваем:

services:
  dockhand:
    image: fnsys/dockhand:latest
    container_name: dockhand
    restart: unless-stopped
    ports:
      - 3000:3000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - dockhand_data:/app/data

volumes:
  dockhand_data:

Композник с официального сайта, там еще есть вариант добавить PostgreSQL, но это уже если у тебя там ебать нагрузки и куча юзеров. Мне хватит дефолтного, пусть оно в sqlite живет, похуй.

Стартуем docker compose up -d и наблюдаем ошибку:

Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint dockhand (a67fe04165e1dab95576a7b6cc5604737938659ff997d84809aea5d1f73587be): Bind for 0.0.0.0:3000 failed: port is already allocated

Ну понятно, чето у меня на 3000 крутится, поэтому в компознике меняю порт на 3002:3000. И перезапускаю. Отлично, даже под ARM из коробки нормально поднялось, а это уже очень ценно! Не все докер образы умеют с армами работать.

Опа, залетели даже без ввода учетных данных, этот момент сразу учитывай если разворачиваешь в открытом интернете. Но это решаемо из коробки.

Создание пользователя

Переходим в Settings → Authentication → Add user и создаем юзера:

И сверху тыкаем на OFF → ON

Перезагружаем страницу и видим форму авторизации. Супер, с этим разобрались.

После этого переходим в Settings → Environments → Add environment

И создаем первое окружение. Я заморачиваться не буду и назову его HOME. Все свои сервисы я буду хостить именно в этом окружении. Но ты можешь все раскидать как тебе хочется и по своим потребностям.

Тут особо ничего менять не нужно, всё по умолчанию в работоспособном режиме. Для проверки нажимаем Test connection и проверяем.

Ништяк. Всё подключилось. Жмем Add и радуемся.

Если у тебя докер каким-то чудным образом работает не через socket, то при добавлении окружения, поменяй Connection type

Так, первый и единственный дашборд у меня готов:

Едем дальше. Нажимаем на окружение и проваливаемся:

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Господи, сколькож всего. На самом деле картинка очень понятная и внятная. Всё перед глазами. Вот в этом и заключается удобство, все необходимые данные на одном экране, не нужно бегать и что-то искать. Сразу видно, что разработчики продумали боль пользователей и решили её достойно. Повторюсь, что в Portainer это ёбаный насос, что-то быстро найти, особенно если ты заходишь в него пару раз в месяц.

Сейчас если нажать Check for update и проверить обновления контейнеров, то получим ошибку. Для РФ классическая ситуация, все забанено, заблокировано, замедленно.

НО. Раз есть проблема, значит её нужно решить, хотя она не такая уж и важная. Ну чё, давай решим раз мы словили неочевидную залупу.

Смотрим логи:

Оуууу, ёбтвою мать! Ну ежу понятно, что с этим делать.

А если ты хочешь так-же, как и я, взглянуть на ошибку и понять что с ней делать, вписывайся в мой интенсив, научу дебажить и разовью в тебе насмотренность. За 2 месяца превратишься в сеньора-помидора.

Фиксим:

docker exec -it dockhand sh
cat /etc/resolv.conf

Docker пытается использовать свой встроенный DNS (127.0.0.11), но у самого Docker нет ни одного внешнего DNS-сервера для пересылки запросов.

Добавляем в композник DNS:

services:
  dockhand:
    image: fnsys/dockhand:latest
    container_name: dockhand
    restart: unless-stopped
    dns:
      - 1.1.1.1
      - 8.8.8.8
    ports:
      - 3002:3000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - dockhand_data:/app/data

volumes:
  dockhand_data:

Снова проверяем обновления иии… ПУШКА!

dockhand выделила рамкой контейнеры, которые можно обновить. НО как показывает практика, после обновления, не факт что у тебя всё будет работать как раньше. Поэтому предварительно запомни на какой версии у тебя работает сервис и только потом обновляйся. Если не взлетело, откатывайся.

Давай чёнить обновим, например Grafana:

Пошла возьня! Проверяем графану:

Работает сучка! Чуть позже обновлю все остальные. Довольно удобно. Кстати, если открыть настройки контейнера, то можно включить автоматическое обновление:

Помимо обновления, ты можешь отредактировать все переменные и другие параметры с которыми запускается контейнер.

Тут же можно задать лимиты на ресурсы, подключить GPU и вообще чёрту хвосты накрутить. Всё гибко и максимально кастомится под хотелки.

А еще можно прям из коробки создавать новые контейнеры со всеми вытекающими настройками. То есть, если терпеть не можешь композники, у тебя есть возможность всё сделать через морду кликая мышкой.

НО настоящие инженеры мышкой не тыкают, поэтому сразу учись писать нормальные композники. В будущем это знание сослужит тебе добрую службу.

Смотрим логи

Тут тоже все интуитивно понятно и на поверхности. Я обычно сначала запускаю docker compose up потом смотрю логи, фикшу баги и только потом запускаю с ключом -d чтобы контейнер стартовал в фоне.

Тут можно стартануть сразу в фоне и позырить нужные логи. Банально конечно, но без логов пофиксить что-то неочевидное, достаточно проблематично. Фича этих логов — можно ставить на паузу, скачивать, автоскролить и т.п. Короче всё сделано для людей.

С шелом тоже всё понятно, проваливайся внутрь, выбираем оболочку, что-то смотрим, патчим:

Но такая простота влияет на твою дальнейшую судьбу, если просидеть пару месяцев с DockHand, то банально сотрется память и ты начнешь гуглить — как войти в интерактивный режим в консоли. Палка о двух концах. Вам шашечки, либо ехать.

Дальше там всё по стандарту, стеки, вольюмы, сети и т.п. Сам посмотришь, мне достаточно логов и шелов, в остальное обычно не лезу. Но например в images можно быстро глянуть какие контейнеры забивают место на диске и не используются:

А кнопкой Prune Unused их можно безболезненно почистить. Выкроешь пару десятков гигабайт без поисков по ncdu.

Управляем Стеками

Так как у меня ранее был Dockge, то DockHand в Source пишет — Untracked, то есть по сути оно мне говорит, что стек создан в другом приложении и иди нахуй. Но и это мы можем исправить и бесшовно переехать, без хуйни и смс.

Для этого правим композник:

services:
  dockhand:
    image: fnsys/dockhand:latest
    container_name: dockhand
    restart: unless-stopped
    dns:
      - 1.1.1.1
      - 8.8.8.8
    ports:
      - 3002:3000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - dockhand_data:/app/data
      - /opt/stacks:/opt/stacks

volumes:
  dockhand_data:

У меня все композники лежат на хосте в /opt/stacks, монтируем эту папку в контейнер DockHand, а затем проваливаемся в контейнер в разделе Stacks:

Нажимаем Browse for compose file и выбираем композник в папке, которую только что примонтировали:

Ага, появился. Теперь жмем Save & Redeplo и наслаждаемся.

Стек перешел в статус — Internal. Минимум телодвижений. Теперь мы можем управлять нашим композником прям из DockHand.

Я повторяю эту процедуру для каждого стека и потихоньку переношу контейнеры. Готово:

Удаленный docker хост

Дада, сюда можно подключить другие докер хосты, чтобы это провернуть, при создании нового Environments выбираем тип соединения: Hawser agent. Логично, что на удаленный сервер, нужно вкорячить агента. Давай попробуем.

Идем на удаленный сервер и запускаем агент:

docker run -d \
  --name hawser \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /opt/hawser-stacks:/opt/hawser-stacks \
  -e STACKS_DIR=/opt/hawser-stacks \
  -p 2376:2376 \
  -e TOKEN=your-secret-token \
  ghcr.io/finsys/hawser:latest

Да, на официальном сайте агента, ты можешь выбрать любой доступный способ запуска. Я выбрал докер, мне так привычнее, не хочу возиться с systemd. Ну и в your-secret-token забиваю секретный ключ, чтобы оно смогло авторизоваться.

Секрет генерим, например так:

openssl rand -base64 32

Проверяем, все ок:

Для пущей безопасности рекомендую сделать сертификат и подключаться по HTTPS. Для демки подойдет HTTP, всеравно там воровать нечего.

Отлично, второе окружение подключено, теперь я могу наблюдать и манипулировать удаленным сервером.

Мля, мякотка!!!

Бонусом TLS

Чё уж вокруг ходить, давай TLS сделаем. Покажу на пальцах, как его внедрить и сделать по взрослому.

docker stop hawser
docker rm -f hawser

docker run -d \
  --name hawser \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /opt/hawser-stacks:/opt/hawser-stacks \
  -v /var/lib/angie/acme/letsencrypt:/certs:ro \
  -e STACKS_DIR=/opt/hawser-stacks \
  -e TOKEN=your-secret-token \
  -e TLS_CERT=/certs/certificate.pem \
  -e TLS_KEY=/certs/private.key \
  -p 2376:2376 \
  ghcr.io/finsys/hawser:latest

У меня сертификаты уже получены с помощью Angie, поэтому я буду использовать их. Как настраивать авто SSL в Angie я рассказывал тут.

Запускаем агент, идем в морду dockhand и выставляем протокол HTTPS (TLS):

Не забываем поменять Agent Host на имя домена, на который выпущены сертификаты. Всё!

Дело в шляпе, теперь всё по взрослому.

Кстати мне удалось пропатчить лицензию и я открыл все Enterprise фичи.

О том как это сделать, напишу чуть позже. В принципе ничего сложного там нет, было бы желание. Всё делалось в рамках эксперимента и проверки продукта на стойкость. Так что авторам продукта волноваться не стоит, но к примеру модули wordpress патчатся намного сложнее.

Комментарии