← До всіх записів
dockercomposeportainer

Docker Compose виявився про керованість, а не про моду

Перевів Uptime Kuma і Portainer з ручного docker run у docker compose, зафіксував exact image tags і прибрав залежність від shell history як головного джерела правди.

15 квітня 20268 хв читанняІнфраструктурні сервіси стали відтворюваними

Docker Compose виявився про керованість, а не про моду

На ранніх етапах docker run здається абсолютно достатнім. І це правда: він чудово підходить, щоб швидко перевірити ідею або просто підняти контейнер.

Але в якийсь момент контейнер перестає бути "тимчасовим експериментом" і стає частиною інфраструктури. І от саме в цей момент уже хочеться не просто запускати сервіс, а керувати ним спокійно і передбачувано.

На моєму сервері цей перехід стався з Uptime Kuma і Portainer.

Як я зрозумів, що сервіс ще не під compose

Перша перевірка була дуже прикладна. Я дивився не на відчуття, а на Docker metadata:

terminal
docker inspect portainer --format 'image={{.Config.Image}}'
docker inspect portainer --format 'compose_dir={{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
docker inspect portainer --format 'project={{ index .Config.Labels "com.docker.compose.project" }}'
docker inspect portainer --format '{{range .Mounts}}{{.Type}} {{.Name}} -> {{.Destination}}{{println}}{{end}}'
docker inspect portainer --format 'restart={{.HostConfig.RestartPolicy.Name}}'
docker port portainer

Ключовий сигнал був простий:

  • compose_dir= порожній
  • project= порожній

Це означало, що контейнер запущений не через docker compose.

Саме така перевірка мені дуже сподобалась, бо вона прибирає здогадки. Не треба згадувати, "наче я колись ось так його запускав". Docker сам каже правду про свій стан.

Uptime Kuma: переведення на compose

Після оновлення я оформив Uptime Kuma як окремий stack:

  • compose directory: /home/ubuntu/docker/uptime-kuma
  • image: louislam/uptime-kuma:2.2.1
  • локальний bind: 127.0.0.1:3001
  • volume: uptime-kuma

Послідовність команд виглядала так:

terminal
docker stop uptime-kuma
docker rm uptime-kuma
cd /home/ubuntu/docker/uptime-kuma
docker compose up -d
docker compose ps
docker inspect uptime-kuma --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
docker ps --filter name=uptime-kuma
curl -I http://127.0.0.1:3001
curl -I https://kuma.bombaworkflows.com

Після цього я вже бачив очікувану картину:

  • контейнер має compose labels
  • compose_dir вказує на реальну робочу директорію
  • локальний порт працює
  • публічний домен працює через nginx

Portainer: той самий принцип, але з важливим нюансом

Portainer спочатку теж працював, але був піднятий як ручний контейнер. Переведення відбувалося за тим самим підходом:

terminal
docker ps --filter name=portainer
docker inspect portainer --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
docker stop portainer
docker rm portainer
cd /home/ubuntu/docker/portainer
docker compose up -d
docker compose ps
docker inspect portainer --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
curl -k -I https://127.0.0.1:9443
curl -I https://portainer.bombaworkflows.com

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

  • compose directory: /home/ubuntu/docker/portainer
  • image: portainer/portainer-ce:2.40.0
  • bind: 127.0.0.1:9443
  • volume: portainer_data

Чому я зафіксував exact version, а не залишив sts

Тут був дуже показовий урок.

Спочатку контейнер ішов на:

terminal
portainer/portainer-ce:sts

Після переведення на compose браузер почав позначати сайт як небезпечний. У той же час базові технічні перевірки виглядали нормально:

  • curl -I віддавав 200
  • HTML сторінка грузилась
  • TLS сертифікат по домену був валідний
  • Portainer в логах стартував без критичних помилок

Реальне виправлення прийшло не з боку compose, а з боку exact image tag. Після того як я замінив:

terminal
image: portainer/portainer-ce:2.40.0

проблема зникла.

Це дуже хороший operational урок:

  • docker compose не дорівнює "оновив до останнього і все буде добре"
  • спосіб керування сервісом і конкретний build образу - це різні речі
  • плаваючі теги дають сюрпризи саме тоді, коли їх найменше хочеться

Що дає docker compose у повсякденній роботі

Після цього переходу знання про сервіси перестали жити в shell history і нарешті почали жити в конфігурації. А це вже зовсім інша якість порядку.

Тепер є:

  • зрозуміла директорія під кожен сервіс
  • файл docker-compose.yml
  • точний image tag
  • передбачуваний restart flow
  • простий upgrade path
  • простий rollback path

І найважливіше: якщо завтра треба буде відтворити сервіс на іншому сервері, для цього вже не доведеться відновлювати події по пам'яті.

Як я перевіряю, що compose-схема справді працює

Мінімальний набір команд, який тепер дає мені спокій:

terminal
docker compose ps
docker inspect uptime-kuma --format '{{.Config.Image}}'
docker inspect portainer --format '{{.Config.Image}}'
docker inspect uptime-kuma --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
docker inspect portainer --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'
curl -I https://kuma.bombaworkflows.com
curl -I https://portainer.bombaworkflows.com

Це одразу відповідає на ключові запитання:

  • що зараз запущено
  • якою версією
  • з якої директорії керується
  • чи доступний сервіс локально і публічно

Висновок

Цей етап навчив мене дивитися на docker compose не як на модний інструмент, а як на спосіб навести лад.

Контейнери не стали швидшими. Інтерфейси не стали красивішими. Але інфраструктура стала:

  • зрозумілішою
  • відтворюваною
  • спокійнішою в оновленнях
  • менш залежною від випадкових ручних дій

І саме тому цей перехід виявився настільки цінним для реального DevOps-навчання.