Docker-контейнеры как основа для self-hosted сервисов
Я являюсь ярым апологетом размещения используемых сервисов на собственном железе в собственной сети. Другими словами, я двумя руками за использование self-hosted сервисов. Но любого, кто решит идти по пути создания такой инфраструктуры, будут поджидать многочисленные каверзные вопросы, требующие иногда довольно нетривиальных ответов.
Это и понятно, ведь вам придется столкнуться с большим количеством программного обеспечения, о существовании которого совсем недавно вы и не подозревали. К тому же, далеко не всегда можно найти внятное описание этого ПО, не говоря уже и о поддержке. Трудности начинаются уже в момент установки, а иногда - и перед ней.
Зачастую, self-hosted сервисы - это программы, написанные для работы в качестве web-приложений в каком-нибудь web-сервере. В качестве последнего, чаще всего, выступает Apache, но может быть,например, nginx, или lighttpd. Кроме того, некоторые из self-hosted сервисов могут сами выступать в роли web-сервера. В общем, тут есть от чего прийти в замешательство.
И в самом деле, пусть тот, кто слышал перечисленные выше названия, поднимет руку. Или нет, зададим вопрос иначе: кто знает что такое web-сервер? А как его установить и настроить? А настроить так, чтобы удовлетворить потребности web-приложения, которое надо установить позже в этот самый web-сервер. А нескольких web-приложений?
Поверьте, я не подзуживаю неопытных пользователей с целью показать свою крутость. Ведь я, например, несмотря на то, что нахожусь в профессии всю свою сознательную трудовую жизнь, не испытывал раньше нужды использовать и изучать все эти серверы и прочие web-технологии. Поэтому, при чтении документации (когда она есть) довольно часто чувствую себя, как герой анекдота, который назвал все буквы, но не смог прочитать слово. То есть, вроде, прочитал, и даже кое-что понял, но как это применить?
И вот тут на помощь приходит технология контейнеризации и Docker, который стал, пожалуй, первым инструментом, который смог ее популяризировать. Я не буду подробно, да и кратко тоже, рассказывать про контейнеризацию и Docker
- в сети много информации по этим темам. Для нас главное заключается в том, что многие производители софта в настоящее время используют Docker
для создания своеобразных установочных пакетов своего ПО.
То есть, каков был бы алгоритм моих действий, если бы я захотел развернуть, скажем, self-hosted платформу для ведения блогов Ghost. Ответ можно найти в документации. И, в принципе, там достаточно доступно расписано, что и как надо установить на новом сервере, чтобы Ghost
заработал. Только вот жизнь бывает немного сложнее.
Скорее всего, в домашних условиях вы вряд ли будете выделять на каждый self-hosted сервис по отдельному серверу. Можно было бы выделять по виртуалке, только вот виртуалки требуют много ресурсов, особенно это касается памяти. Так что, скорее всего, придется несколько self-hosted сервисов устанавливать на один сервер (или одну виртуалку). И тут могут начаться пляски с бубном.
Так, например, на этом сервере уже мог быть установлен сервер БД MySQL
, так как, весьма вероятно, он нужен был для работы с другим сервисом, установленным ранее. Возникает вопрос, стоит ли использовать этот уже существующий экземпляр. Ведь, теоретически, можно установить и новый, только вот с настройками придется повозиться, чтобы они (старый и новый) друг другу не мешали. В случае же использования старого экземпляра, надо быть внимательным и осторожным, чтобы установленные в один экземпляр БД различные схемы данных не мешали бы друг другу. Конечно же, не надо драматизировать. Я, например, устанавливал различные сервера БД и так и эдак, так что, могу вас уверить, все решаемо. Хотя, может, поэтому и не нервничаю - потому, что имею опыт?
А вот nginx
, или node.js
я не устанавливал. Ну, с nginx
я, допустим, преувеличил, с ним приходилось работать. Но что за зверь такой - node.js
- я знаю весьма и весьма поверхностно, и как обеспечить его функционирование одновременно для различных сервисов, мне неведомо. Более того, неведомо даже то, имеется ли такая возможность в принципе. Но я знаю, что очень часто приложения не любят обновлений node.js
, и ситуации, когда разным приложениям нужны разные версии node.js
встречаются сплошь и рядом. Не известно мне лишь то, как вообще устанавливать node.js
и, тем более, как установить несколько экземпляров разных версий на один сервер. И опять же, вряд ли это - безвыходная ситуация: документация и гугл не дадут пропасть. Но то для меня, человека, который всю жизнь только и делает, что что-то устанавливает и с чем-то разбирается. А что делать простому пользователю, который не имеет такого опыта?
И, честно говоря, Docker
выглядит очень заманчиво в качестве ответа на этот вопрос. Что делает производитель софта при использовании Docker
? Не углубляясь в технические подробности, на бытовом, так сказать, уровне, можно сказать, что он собирает образ диска, содержащего и его продукт и весь набор ПО, необходимый для его нормального функционирования. При этом, все внутренние настройки производятся производителем же - кто, как не разработчик, знает, что и как нужно настроить, чтобы все работало самым замечательным образом. При этом, у того, кто готовит этот образ, есть выбор: запихнуть все ПО в один образ диска, или же опереться на другие образы, подготовленные разработчиками соответствующих используемых продуктов.
Что же делает пользователь при использовании Docker
? Конечно, на сервере у вас должен быть установлен сам Docker
- без него никакие образы дисков вам не нужны. К счастью, установить его (например, на Debian) совсем не сложно. Далее, вы ищите в реестре образов дисков Docker нужный вам дистрибутив (например, Ghost) и, при помощи Docker
, скачиваете его к себе, ипользуя простую команду:
docker pull ghost
После этого, все что остается сделать - запустить загруженный образ с определенными параметрами. Параметров этих, как правило, немного, и они бывают достаточно хорошо задокументированы разработчиком образа. Вот пример:
docker run -d --name my-ghost -p 8000:2368 -v /path/to/ghost/blog:/var/lib/ghost/content ghost
При помощи этой команды мы запускаем контейнер Ghost
с именем my-ghost
в режиме detach
(фоновом режиме) из образа диска ghost
, загруженного ранее. При этом порт 8000
компьютера, на котором все это дело происходит, ставится в соответствие порту 2368
вашего контейнера (это порт по умолчанию, на котором "слушает" Ghost
). Кроме того, часть файловой системы хоста, а именно, /path/to/ghost/blog
, монтируется в качетве каталога /var/lib/ghost/content
контейнера, и делается это, исходя из следующих соображений. Дело в том, что при повторном запуске Docker
создаст новый контейнер, а старый будет забыт. А вместе с ним будут забыты (но не утеряны) и все те данные, которые вы успели туда записать. К счастью, из этой ситуации есть несколько выходов, один из которых - дать Docker
-у указание при создании контейнера примонтировать к нему часть файловой структуры своего сервера. В этом случае, записываемые вами данные попадут к вам на сервер, и при следующем запуске данные будут доступны новому контейнеру, так как монтирование файловой структуры повторится.
Вот и все! В момент запуска Docker
из образа диска создаст контейнер, в котором и будет работать нужное вам ПО.
На самом деле, эта тема требует значительно более глубокого освещения, и я буду продолжать ее, в том числе, и на примере используеумых мною сервисов... Так что, продолжение следует...