Просто о сложном - Docker
UPD 2023.12.15
Статья нуждается в реанимации. "Просто о сложном" получилось как "Сложно о простом". Сейчас конец 2023 года, ау. Дети рождаются с kubernetes в голове!
Кстати, на этом же сайте, в /docs есть раздел, посвященный докеру. Там современные полезные штучки
Docker — платформа для запуска приложений в изолированных контейнерах.
Простой пример. Будь докер в жизни, вы бы смогли поставить посреди комнаты пакет, а лучше сразу несколько, где в первом у вас будет взрывчатка, а во втором то, что вы хотите подорвать и вот сами вы выступаете в роли спички, фитиля и волшебника, который делает так, чтобы содержимое второго пакета взорвалось, не унеся с собой квартиру и жизнь волшебника за компанию.
Только пакетов не обязательно 2 и в них не обязательно что-то опасное, да и комната (сервер) тоже может быть не одна. Реальные примеры с применением будут описаны ниже.
Вместо "прежде, чем мы начнем"
Нет ничего сложного в использовании докера. Для большинства задач нужны совсем поверхностные знания, которые можно получить, почитав всего пару статей или, еще лучше, раздел Get started официальной документации, затем подкрепить все эти знания практикой. Например, запустить MySQL сервер + Adminer в один клик на этой странице. Там есть кнопочка. Но это только для начала.
Photo by Danielle MacInnes / Unsplash
Для вас это может быть очевидным, но для меня, как человека, который для всех задач искал панель управления было тяжело осознать одну простую вещь:
С Docker придется понять, что теперь не панель управления, а вы должны будете придумать, где разместить ваши данные из контейнера, будь то сайт или что-то еще
Тоесть, теперь не будет никаких кнопочек а-ля "Файловый менеджер", которые сразу о ткроют вам папочку с данными ваших контейнеров. Вы должны сами придумать, где будете работать. У меня это ~/dockerfiles/somefolder
.
И маленькое замечание насчет безопасности - вам придется выполнять все команды или от рута или от sudo или добавить вашего пользователя в группу docker (лучше последнее)
А еще насчет портов. Есть Docker port, а есть Published port. Docker port это порт, который контейнер будет считать, что использует, а Published это порт, через который будет доступен Docker port на родительской машине. Простыми словами, это проброс портов
Основные понятия
Контейнер
Это как виртуальная машина. Его можно удалить, остановить, возобновить, подключиться к терминалу. В общем, делать все, что и с обычным linux сервером или виртуальной машиной
Dockerfile
Это набор инструкций, как нужно создавать контейнер. Пример такого файла можно увидеть здесь. Описание основных инструкций вот здесь
docker-compose.yml
В докере один Dockerfile это один сервис. Если вам нужен один сервис, например, торрентокачалка или генерация LetsEncrypt сертификата, вы можете запустить его через docker run
. Но если у вас приложение, состоящее из нескольких сервисов (PHP + Nginx + MySQL), то запускать их все по очереди длинными командами с кучей параметров было бы, как минимум, неудобно. Этот файл объединяет все в одном месте и управляется через команду docker compose
Я выделил популярные команды. Они частично будут описаны ниже
Репозиторий
Есть репозитории, а есть Automated builds. По-простому, репозитории это готовые сборки систем. Например, чистый Ubuntu. Некоторые репозитории это сразу система с установленным приложением, например, CMS Ghost. На Docker HUB репозиторий это куча файлов, а Automated build это всего лишь Dockerfile
Automated build
На первый взгляд ничем не отличаются от репозиториев. Мне даже трудно объяснить разницу. По-обезьяньи я понимаю это так: "у репозиториев я не могу посмотреть Dockerfile, а у autobuilds могу". Automated builds это те же репозитории, только с них вы можете без проблем забрать Dockerfile и поправить его под свои нужды.
Также со временем Automated build может перестать работать, если какая-то инструкция в нем устареет (например, Dockerfile писался под Ubuntu 14.04 (FROM ubuntu:latest
), а со временем ubuntu:latest обновилась до 18.04 и вжух, проблемы). Репозитории в этом плане монолитные. Какими залиты, такими и будут даже через 100 лет.
Еще есть всякие инструкции для Dockerfile, вроде ADD
и COPY
, которые добавляют файлы в контейнер во время его создания и которые не работают для репов
Пример Automated Build: cpuminer-multi
Swarm
Вы можете даже ни разу не столкнуться с этим на практике, но на будущее - это что-то вроде кластера. Короче, связка серверов с установленным Docker.
В нем есть главная нода и подчиненные. Главная это та, на которой выполнен docker swarm init
, а подчиненные те, которые присоединились через docker swarm join
и готовы принимать указания от главной (docker stack deploy
)
Способы применения
- Можно без проблем изучать новые фишки, до которых раньше руки не доходили из-за сложности или не хотелось засорят ь систему. Например хотели простой блог на JavaScript, торрент качалку или даже целый комбайн из приложений с кучей мусора и зависимостями без заморочки - докер.
- Если вы раньше использовали VirtualBox для запуска приложений, то Docker его не только заменит, но и сделает все быстрее и проще
- Он поможет запустить приложение любой сложности на любой системе всего в пару нажатий клавиш при помощи всего лишь одного Dockerfile файла. Или docker-compose.yml , если нужно запустить пачку сервисов.
- Благодаря докеру вы можете собирать данные кучи приложений в одном, нужном вам месте, благодаря чему их проще будет переносить.
- Или, например, у вас есть веб приложение с кучей заточенных под вас настроек, всяких баз данных, веб серверов, фреймворков и тд и вам нужно расширяться, копировать все это на другие сервера, прописывать все заново. С докером вы выполняете
docker swarm init
на главной ноде иdocker swarm join
на всех подчиненных, затем с главной передаете всем остальным задачу деплоя ваших приложений/сервисов при помощи пары команд. - Еще пример. Вы когда-нибудь использовали WAMP? Это связка
Apache + PHP + PHPMyAdmin + MySQL
и еще пары ништяков, которые помогают PHP разработчкам писать и тестить сайты, сидя на винде без всяких виртуалок. Так вот WAMP полезен только на винде и только для PHP. А Docker полезен хоть на Windows, хоть на Linux, хоть на Mac OS и для чего угодно, а не только PHP разработчиков
Кстати, этот блог запущен внутри Docker контейнера, а рядом с ним крутится еще контейнер с Nginx, контейнер с MariaDB, при необходимости, запускаю еще контейнер с Adminer (Аналог phpmyadmin) и LetsEncrypt генерилкой. Благодаря этому я могу купить еще хоть 100 VDS с Docker, одной командой подключить их к одному swarm'у (кластеру) и запустить сразу на всех мой блог так же в одну команду. Тогда даже если 99 нод "умрут", блог все равно будет доступен на последней.
Шпаргалка по популярным командам
Запуск контейнера
- Фоновый (Запустили и отключились detach)
docker run -d mysql
- Со своим названием
docker run --name database mysql
- Этот удалится после отключения от него или выполнения задачи
docker run -rm ubuntu pwd
- Проброс порта с контейнера на хост. Слева порт на хосте (Published)
docker run -p 8080:80 -d nginx
- Остановка работающего (Данные внутри сохраняются. Запуск через start)
docker stop NAME
- Удаление контейнера (Проброшенные в него файлы сохраняются)
docker rm NAME
(-f удаляет даже если контейнер запущен)
Отладка
- Подключение к терминалу контейнера
docker exec -it NAME bash
- Посмотреть логи внутри контейнера (STDOUT, STDERR)
docker logs -f NAME
Управление образами
- Сборка образа контейнера на базе Dockerfile (точка в конце нужна)
docker build --tag image-name .
- Список
docker images -a
- Удаление
docker image rm NAME
(-f force) - Переименование
docker image tag SOURCE[:TAG] TARGET[:TAG]
docker-compose
- Создание/обновление контейнеров приложения в фоне (-d)
docker compose up -d APP_NAME
- Остановка
docker compose stop
- Запуск остановленного приложения
docker compose start
- Остановка и удаление
docker compose down
- Логи всех сервисов приложения
docker compose logs -f
Другие полезности
- Работающие и остановленные контейнеры
docker ps -a
(Без -a только работающие) - Показать данные контейнера (Тут можно найти его IP, пути к volumes и кучу другого)
docker inspect NAME
Чистка мусора
- Удалить все остановленные контейнеры
docker rm $(docker ps -a -q)
- Удалить незакрепленные ни за каким контейнером volumes
docker volume rm $(docker volume ls -f dangling=true -q)
- Удалить неиспользуемые сети
docker network prune
- Удалить все неиспользуемые данные
docker system prune -a
- Удалить контейнеры, что остановлены больше часа назад + образы, с которыми не работает ни один контейнер (продвинутый способ)
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc:ro spotify/docker-gc
Вместо вывода
Небольшой лайфхак, как разобраться в Docker со скоростью света - изучайте чужие Dockerfile и docker-compose.yml и не ленитесь читать официальные документации, там все написано максимально кратко. Нельзя выучить докер за 5 минут, но сколько бы времени вы не потратили на его изучение, это того стоит.
Ништяки
- Docker WEB Panel
docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/portainer:/data portainer/portainer
тут русский обзор - OpenVPN сервер на Docker
- Garry's Mod сервер через Docker (мое изобретение :))
- Торрентокачалка
- Ghost (blog CMS на JS)
- cpuminer