Подготовка сервера Ubuntu и установка среды Docker
Подготовка сервера Ubuntu и установка среды Docker
До появления стандартизированных морских контейнеров в 1950-х годах погрузка судна была хаотичным процессом: бочки, мешки и ящики загружались вручную, часто повреждая друг друга. Изобретение универсального стального контейнера изменило мировую логистику — теперь портовым кранам неважно, что внутри: автомобили или бананы. Они работают со стандартным блоком. В мире разработки программного обеспечения похожую революцию совершил Docker.
Развертывание сложных веб-приложений, таких как Rocket.Chat, исторически требовало ручной установки множества компонентов. Вам нужно было бы установить правильную версию среды выполнения Node.js, настроить базу данных MongoDB, убедиться, что их версии совместимы с вашей операционной системой Ubuntu, и разрешить конфликты зависимостей, если на сервере уже крутятся другие проекты. Docker устраняет эту проблему, упаковывая приложение и все его зависимости в изолированные, стандартизированные программные блоки — контейнеры.
Архитектура: почему именно Docker
Традиционный подход к изоляции приложений — использование виртуальных машин (ВМ). Виртуальная машина эмулирует аппаратное обеспечение и запускает полноценную гостевую операционную систему поверх вашей основной (хостовой) ОС. Если вам нужно запустить три изолированных приложения, вы запускаете три виртуальные машины, каждая из которых потребляет гигабайты оперативной памяти и процессорное время просто на поддержание работы собственных ядер ОС.
Docker использует другой подход — контейнеризацию на уровне операционной системы.
Контейнеры не содержат собственной операционной системы. Они используют ядро вашей хостовой Ubuntu, но при этом изолированы друг от друга на уровне процессов, файловой системы и сети. Это делает их невероятно легковесными: контейнер запускается за доли секунды и потребляет ровно столько ресурсов, сколько нужно самому приложению, без накладных расходов на эмуляцию ОС. Для Rocket.Chat это означает, что база данных и сам мессенджер будут работать в изолированных средах, не засоряя системные директории вашего сервера, но при этом работать так же быстро, как если бы они были установлены напрямую в Ubuntu.
Подготовка операционной системы
Любая работа с новым сервером на базе Ubuntu начинается с обновления системных пакетов. Пакетный менеджер apt (Advanced Package Tool) использует локальную базу данных, в которой хранится информация о доступных программах и их версиях в официальных репозиториях.
Если сервер был установлен некоторое время назад, эта база данных устарела. Попытка установить новое программное обеспечение со старой базой может привести к ошибкам 404 (сервер не найдет старую версию программы по ссылке) или к нарушению зависимостей.
Процесс обновления состоит из двух строго последовательных шагов. Сначала необходимо обновить саму базу данных пакетов:
sudo apt update
Команда update ничего не устанавливает. Она лишь скачивает актуальные списки программ с серверов Ubuntu и сравнивает их с тем, что установлено у вас. После выполнения этой команды терминал часто сообщает, что определенное количество пакетов может быть обновлено.
Второй шаг — фактическая установка новых версий:
sudo apt upgrade -y
Флаг -y (yes) автоматически отвечает утвердительно на вопрос системы «Хотите ли вы продолжить?», что экономит время. Процесс upgrade скачает и установит последние патчи безопасности и минорные обновления для системных утилит. Это критически важный фундамент: установка сложных сред вроде Docker на необновленную систему — прямой путь к конфликтам библиотек.
Установка среды Docker
Существует несколько способов установить Docker на Ubuntu: из стандартных репозиториев Ubuntu, через добавление официального репозитория Docker или с помощью автоматического скрипта.
Для быстрого и надежного развертывания оптимален официальный скрипт автоматической установки. Он самостоятельно определяет версию вашей операционной системы, архитектуру процессора, добавляет нужные GPG-ключи (цифровые подписи, гарантирующие подлинность скачиваемых файлов) и устанавливает самые свежие стабильные версии всех необходимых компонентов.
Выполните в терминале следующую команду:
curl -fsSL https://get.docker.com -o get-docker.sh
Разберем, что здесь происходит. Утилита curl обращается к веб-серверу по указанному адресу и скачивает содержимое.
- Флаг
-f(fail) заставляетcurlтихо завершиться с ошибкой, если сервер недоступен, не выдавая мусорный HTML-код в терминал. - Флаг
-s(silent) скрывает прогресс-бар скачивания. - Флаг
-S(show-error) в комбинации с-sгарантирует, что если ошибка всё же произойдет, мы её увидим. - Флаг
-L(location) позволяет переходить по редиректам, если файл переехал. - Конструкция
-o get-docker.shсохраняет скачанный текст в локальный файл с названиемget-docker.sh.
Теперь этот скрипт нужно запустить с правами суперпользователя:
sudo sh get-docker.sh
Процесс займет от одной до нескольких минут в зависимости от скорости интернет-соединения сервера. Скрипт установит docker-ce (Community Edition — сам движок), docker-ce-cli (инструмент командной строки для управления движком) и containerd.io (низкоуровневую среду выполнения контейнеров).
Настройка прав доступа
По умолчанию архитектура Docker состоит из двух частей: фоновой службы (демона), которая выполняет всю тяжелую работу по созданию и запуску контейнеров, и клиентской утилиты командной строки (CLI), через которую мы отдаем команды.
Демон Docker взаимодействует напрямую с ядром Linux и требует прав суперпользователя (root). Поэтому, если вы попытаетесь выполнить команду docker ps (показать запущенные контейнеры) от имени обычного пользователя, вы получите ошибку вида permission denied while trying to connect to the Docker daemon socket.
Чтобы не писать sudo перед каждой командой Docker, необходимо добавить вашего текущего пользователя в специальную системную группу docker, которая создается автоматически при установке.
sudo usermod -aG docker $USER
Эта команда требует предельной осторожности при ручном вводе, если вы не используете копирование.
Утилита usermod модифицирует учетную запись пользователя.
Флаг -G указывает список дополнительных групп.
Критически важен флаг -a (append — добавить). Если вы напишете usermod -G docker $USER без -a, система удалит вашего пользователя из всех остальных групп, в которых он состоял (включая группу sudo), и оставит только в группе docker. Это приведет к потере прав администратора на сервере. Системная переменная $USER автоматически подставляет имя пользователя, под которым вы сейчас авторизованы.
Чтобы изменения вступили в силу, операционной системе нужно заново оценить ваши права. Самый надежный способ — полностью разорвать SSH-соединение с сервером (команда exit) и подключиться заново.
Docker Compose: оркестровка контейнеров
Сам по себе движок Docker отлично справляется с запуском одиночных контейнеров. Однако современные приложения редко состоят из одного компонента. Rocket.Chat — это сложная система, которой для работы требуется как минимум сам сервер приложения и отдельный сервер базы данных (MongoDB).
Запускать их вручную отдельными командами, прописывая длинные списки параметров сети и томов для сохранения данных, неудобно и ненадежно. Для решения этой задачи был создан Docker Compose.
Docker Compose — это инструмент, который позволяет описать всю инфраструктуру приложения в одном текстовом файле формата YAML. В этом файле фиксируются версии образов, пароли, сетевые связи между контейнерами и правила перезапуска. Вместо десятка команд вы выполняете одну, и Compose сам выстраивает нужную архитектуру.
В современных версиях Docker (которые устанавливаются через скрипт get.docker.com) Compose уже включен в состав системы как плагин. Проверить его наличие можно командой:
docker compose version
Вы должны увидеть вывод, похожий на Docker Compose version v2.24.5. Обратите внимание на синтаксис: мы пишем docker compose через пробел. В старых инструкциях в интернете часто встречается написание через дефис (docker-compose) — это устаревшая версия инструмента, написанная на Python, тогда как современный плагин написан на Go и интегрирован в основной CLI.
Проверка работоспособности среды
Чтобы убедиться, что вся цепочка (демон, права пользователя, доступ в интернет) работает корректно, в мире Docker принято запускать тестовый контейнер hello-world.
docker run hello-world
Эта простая команда запускает сложную последовательность действий, которая является основой работы с любым приложением в Docker.
Когда вы нажимаете Enter, происходит следующее:
- Клиент Docker обращается к фоновому демону и передает ему команду запустить образ
hello-world. - Демон проверяет локальное хранилище сервера. Поскольку мы только что установили Docker, образа там нет.
- Демон автоматически подключается к Docker Hub (официальному публичному реестру образов) и скачивает (pull) нужный образ оттуда.
- Из скачанного образа демон создает новый изолированный контейнер и запускает внутри него программу.
- Программа выводит в ваш терминал приветственное сообщение, объясняющее, что установка прошла успешно, после чего завершает свою работу. Контейнер переходит в остановленное состояние.
Если вы видите сообщение, начинающееся со слов «Hello from Docker!», значит базовый фундамент полностью готов. Сервер обновлен, среда контейнеризации установлена, права настроены корректно, а плагин Compose ожидает инструкций. Инфраструктура готова к тому, чтобы принять конфигурационный файл и развернуть полноценный сервер Rocket.Chat.