Всем привет, хочу рассказать о своей утилите dcw (Docker Compose Workspace) для удобного управления тестовыми окружениями на базе docker-compose.
Расскажу немного о проблеме, которую я попытался решить. Я разработчик, занимаюсь в том числе, разработкой бэкендов на разных языках и стеках. Так получилось, что у меня много проектов, которые я разрабатываю или занимаюсь поддержкой. Наверное у многих такая история.
У меня есть такая проблема как переключение между проектами, которое может происходить довольно часто, даже по несколько раз в день. Раньше было как без докера? На машине разработчика устанавливался весь необходимый софт, базы данных Postgres, Redis, какие-то вспомогательные сервисы, такие как Keycloak, Apache PHP, Java... Возможно каждый сервис или язык разработки представлен ещё и несколькими разными версиями. В общем такой зоопарк операционка долго не могла нормально переносить и по итогу, что-то с чем-то конфликтовало, что-то всё-равно где-то ломалось и приходилось переустанавливать всё заново и с этим бороться. В общем это был ад.
Как же хорошо что сейчас есть docker и мы можем все необходимые сервисы, языки и прочее запускать в нём. Можно для описания тестового dev окружения использовать docker-compose, это ещё упрощает жизнь в плане запуска и останова.
Более того, например, VSCode поддерживает Dev Containers и может за нас проделывать всю работу по запуску и останову dev окружения. Но к сожалению, это не полностью спасает, так как есть ещё другие IDE, в которых такой поддержки нет.
Поэтому я остановился на том, что у меня в каждом проекте есть папочка с docker-compose.yml
, который поднимает все необходимые дополнительные сервисы для локальной разработки и вручную его запускаю и останавливаю. Однако тут есть некоторые неудобства, приходится каждый раз глядеть какое из окружений запущено из других проектов, и если это не то окружение, какое в данный момент необходимо, то идти в папку с docker-compose.yml
в другом проекте, останавливать, а потом идти в папку требуемого проекта, там искать docker-compose.yml
и запускать.
Много ручной работы, переключений между проектами много. Немного пострадав, я написал себе простенькие bash скрипты, которые запоминали текущий docker-compose.yml, потом останавливали его и запускали новый. Скрипты лежали в ~/bin
и выглядели примерно так: switch_to_some_project
, switch_to_another_project
...
И вот настало время и я решил сделать это по человечески, так появилась утилита dcw
(https://github.com/navrocky/dcw).
Она написана на C++, скомпилирована в статику с рантаймом uClibc, работает без пересборки на всех возможных Линуксах (x86, x86_64), также работает в docker from scratch (правда не знаю зачем, но работает). Устанавливается простым копированием бинарника в /usr/local/bin
или в ~/bin
. Кому интересно как собирать такие статические бинарники можете заглянуть в докер файл Dockerfile.uclibc.
Позволяет добавлять docker-compose.yml
файлы в свою локальную БД, присваивать alias и потом по этому alias быстро переключаться между ними. Имеется в наличии автодополнение для bash, поэтому не обязательно полностью вводить команды и алиасы, достаточно пощёлкать табом.
Хотелось бы добавить её в популярные дистрибутивы, но там как-то всё сложно с этим, я пока эту затею не реализовал. Если кто-то в комментариях напишет как можно добавить свой пакет, например, в Ubuntu я был бы очень признателен.
Очень надеюсь, что эта утилита кому-нибудь будет полезна. Спасибо за внимание.
Комментарии (17)
Alekseyl
23.04.2024 21:02+4Проблема актуальная, да. Я её иногда решаю примерно так:
docker stop $(docker ps -q) && docker compose up -d
Это остановит все ранее запущенные контейнеры и поднимет те, что описаны в docker-compose.yaml в текущей папке.
В случае с Windows и PowerShell, правда, приходится вместо && использовать ;, но в данном случае это не критично.
Длинно, да, но так как аргументы тут менять не нужно — достаточно просто нажать Ctrl+R в терминале.
opusmode
23.04.2024 21:02+9Ну, как бы, такое...
Вообще говоря, уже давно мжно давать сервисам имена
Буквально берём compose.yml и пишем
name: app
потом делаем docker compose up -d и docker compose ls и видим name. Собственно в name будет входить всё связанное с проектом. Далее корректнее погасить через docker compose -p app down. И не говрите, что у вас сотни миллиардов запущенных проектов и вы замучаетесь переключать - это проблема на вашей стороне.
Плюс докер умеет в профили. Т.е. каждому сервису можно повесить профиль и запускать (А так же гасить) только нужные профили приложения.
Вообще, самая актуальная проблема с докером в том, что он уже лет 10 как перешёл из разряда хайпа, в разряд обычного инструмента, а люди так и не научились работать с ним и до сих пор лепять какую-то непонятную дичь. ОСобенно это любят делать как раз разработчики, которые делаю докер ради докер, даже там, где он нафиг не нужен.
mayorovp
23.04.2024 21:02+1Не надо давать имена, и уж точно не такие фиксированные.
Одна из фич docker compose - в возможности развернуть несколько независимых проектов рядом. Однако любое фиксированное имя сервиса вызовет конфликт.
opusmode
23.04.2024 21:02Что значит "не надо давать имена"? Кому не надо, тот пусть не даёт. Функция есть. Мне надо - я даю.
Что значит "такие фиксированные"? Я привёл пример. Вы знаете, что такое пример? Это абстракция. Я не буду придумывать за вас имена.
-
Это не фича docker compose. Это фича docker. Compose Это удобная обёртка, чтобы не пилить конструкции страшного содержимого. И имена вам вообще никак не мешают развернуть несколько независимых проектов рядом.
Более того, расскажу вам очень крутую фишку. Когда-то, 10+ лет назад, когда я ещё был зелёным джуном в джава разработке и не ушёл в инфраструктуру, была там такая штука, как полиморфизм и такая опция, как Override. Я, конечно, извиняюсь, наверное мои знания остались в глубокой древности и современные разработчики не используют такие отсталые инструменты, но в моём мышлении описанная конструкция это всё ещё схема, а итоговая реализация может быть допилена. Так вот, вы не поверите, но описанное в compose.yml это дефолтное значение переменной и его можно переопределить через туже опцию -p или через длинный ключ --project-name. Так что даже если у вас что-то, внезапно, не запустится, а такое иногда бывает, когда Network занят чем-то, то можно просто пересобрать.
Расскажу вам ещё пару хинтов. В докере есть понятие образа, т.е. шаблона изделия и контейнера, т.е. конечной реализации. Как я уже сказал, compose это просто удобный способ делать что-то. Правда бывают ситуации, при которых там описан не image а dockerfile, т.е. образ надо предварительно сбилдить. Потому вызнать надо будет, по хорошему, docker compose --build up -d.
А иногда надо сделать docker compose up -d --force-recreate.
А ещё надо помнить, что погашеный контейнер всё равно существует и может тянуть за собой пачку всякого. Так что иногда неплохо сделать что-то врде docker system prune. Ну, знаете, место освобождает, удаляя кешированые слои, вольюмы с нетворками лишние убирает, а самое офигенное - не трогает текущие контейнеры.
zorn-v100500
23.04.2024 21:02Вообще, самая актуальная проблема с докером в том, что он уже лет 10 как
перешёл из разряда хайпа, в разряд обычного инструмента, а люди так и
не научились работать с ним и до сих пор лепять какую-то непонятную
дичь.Вот да. По заголовку зашел сказать что то такое, но уже сказали )
Вообще сам всегда запускаю `up` без `-d` чтобы висело где то в консоле `vscode` и по CTRL+C потушить можно было. Ну и не представляю зачем нужно держать кучу запущенных проектов разом. Хотя и делаю всякие финтифлюшки типа
ports: ["${DOCKER_HTTP_BIND:-8000}:80"]
Чтобы в `.env` можно было указать другой проброшеный на машину порт.
opusmode
23.04.2024 21:02Можно демонизировать, можно не демонизировать, это вопрос вкуса и потребности.
Просто я уже немного задолбался переписывать кучу всякого за непонятными неумехами.
Люди до сих пор не поняли, что такое контейнеризация и как её использовать. Да и что такое cloud native тоже не поняли. И что такое stateless приложение это тоже вызывает ступор и панику.
Очень часто докер вообще нафиг не нужен, в частности разработчику. Куда чаще нужно навести порядок и начать делать как-то иначе. Т.е. не пытаться решить то, что кажется проблемой, а перестроится и уничтожить их как явление. Инае потом получаются монструозные конструкции, которые работают как попало, а самое главное - зачем они это вообще делают?
zorn-v100500
23.04.2024 21:02+1Очень часто докер вообще нафиг не нужен, в частности разработчику.
Тут не соглашусь. Я всегда от всяких очередей и редиса сторонился именно потому что не было докера.
Я за подход "запустил одну команду и разрабатывай", а не "установи X Y Z, ах точно еще про A B и C забыли" на свой комп.
`./bin/dev-start` и погнал )
#!/bin/bash
set -e
cd `dirname $0`/..
. bin/.init
./bin/db-init
. .env
export ACT_UID=${SUDO_UID:-${UID}}
docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up
navrocky Автор
23.04.2024 21:02В целом да, указание имени немного облегчает жизнь. Но это не решает полностью проблему, которую я описал и для чего предназначена эта утилита.
Если вы погасили проект по имени, то поднять его по имени уже не получится, надо идти в папку с docker-compose и там писать docker-compose up -d
Чтобы быстро переключиться нужно значительно больше писать в консоли:
docker compose ls
docker compose -p app down
docker-compose up -f where/is/my/project/docker-compose.yml -d
вместо:
dcw up my_project
Так что я считаю, что кому-то это будет наверняка полезно. Мне вот удобно.
navrocky Автор
23.04.2024 21:02У меня ещё есть идея сделать гуёвое приложение, чтобы висело в трее и было видно какое пространство запущено, ну и в выпадающей менюшке была возможность переключить. Жалко что статический бинарь уже не получится.
MadridianFox
23.04.2024 21:02Есть вариант попроще - вывести текущий воркспейс в bash prompt.
Ну или сделать интерфейс управления в виде веб-приложения, которое показывает какое окружение запущено, позволяет запустит/остановить, и может даже показывает адреса компонентов, получая их из docker inspect (container name + container ip + exposed port) или же из лейблов контейнеров если они заданы
MadridianFox
Похоже на ELC
navrocky Автор
Да, бегло глянул, вроде что-то похожее, но выглядит сложнее. Для себя почерпнул идею, что можно переключаться без указания имени воркспейса, если находишься в папке проекта. Надо будет сделать.
navrocky Автор
Сейчас ещё раз глянул на описание. Да, я кстати думал наворотить функционал, чтобы поддерживался не только докер. Наверное должно было бы получиться совсем что-то похожее на ELC. Но я сдержался и решил сделать что-то простое под конкретную задачку с docker-compose.