Эта статья подойдет ко всем версиям Ubuntu/Debian т.к. команды распознают версию ОС и загружают пакет из требуемого репозитория.

В своем рабочем проекте, я занимаюсь администрированием серверной инфраструктуры. Недавно возникла необходимость оптимизировать использование ресурсов. Ранее мы использовали виртуализацию, но пришло время пересмотреть этот подход.
Выбор пал на Docker благодаря простоте и скорости развертывания пакетов в контейнерах. Это в разы сократило использования ресурсов серверов и временные затраты. К тому же бэкапы создаются куда быстрее, и весят намного меньше.

1. Обновление системы

apt update && apt upgrade -y

2. Установка Docker

Устанавливаем требуемые пакеты:

sudo apt install apt-transport-https ca-certificates curl software-properties-common

Разбор команды

apt-transport-https - обеспечивает поддержку транспорта HTTPS для apt, что позволяет загружать пакеты по защищенному протоколу HTTPS. По умолчанию, когда вы используете официальные репозитории Ubuntu (основные репозитории), пакеты обычно загружаются по протоколу HTTP, а не HTTPS.

ca-certificates - пакет который содержит сертификаты общедоступных удостоверяющих центров, которые используются для проверки подлинности сертификатов при установке пакетов по HTTPS. Linux поставляется с набором корневых сертификатов поэтому этот пакет не является строго обязательным к установке, но что бы быть уверенным в том, что в последующем не будет проблем - рекомендуется поставить.

curl: Утилита для передачи данных по различным протоколам с использованием URL. Часто используемая для скачивания файлов или взаимодействия с веб-сервисами.

software-properties-common: Этот пакет предоставляет общие утилиты для управления настройками репозиториев программного обеспечения. Из данного пакета будем использовать утилиту add-apt-repository.

Загружаем GPG-ключ (открытый ключ подписи):

curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo apt-key add -

Разбор команды

Этот процесс помогает обеспечить целостность и подлинность пакетов, которые собираемся устанавливать в своею систему.

GPG (GNU Privacy Guard) ключ – это пара криптографических ключей, используемых для обеспечения безопасности и подлинности в цифровой подписи и шифровании данных: Открытый ключ (Public Key) и Закрытый ключ (Private Key).

Опции -fsSL в команде curl значит следующее:

f (или -fail): Эта опция заставляет curl вернуть ненулевой код возврата в случае ошибки HTTP. Это может включать различные коды состояния HTTP, такие как 404 (Not Found), 500 (Internal Server Error) и другие.

s (или -silent): Эта опция отключает вывод прогресса и других информационных сообщений. Она используется для того, чтобы команда выполнялась "тихо", без вывода лишней информации.

S (или -show-error): Эта опция противоположна s и заставляет curl показывать ошибки и сообщения об ошибках, даже если s используется. Это полезно для обеспечения видимости ошибок в случае возникновения проблем.

L (или -location): Эта опция заставляет curl следовать перенаправлениям при запросе ресурса. Если запрошенный ресурс возвращает код состояния перенаправления (например, 301 или 302), curl повторяет запрос по указанному новому адресу.

Таким образом, комбинация -fsSL используется для выполнения тихого запроса с автоматическим следованием перенаправлений и прерыванием выполнения в случае возникновения ошибок.

Затем добавляем этот открытый ключ в систему с помощью команды sudo apt-key add - Теперь система "знает" об этом ключе.

Добавляем в систему Ubuntu новый репозиторий для установки Docker:

sudo add-apt-repository "deb [arch=amd64] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable"

Разбор команды

add-apt-repository: Это утилита, предназначенная для добавления новых репозиториев в систему APT (Advanced Package Tool). В данном случае, это используется для добавления репозитория Docker.

"deb [arch=amd64] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable": Это параметры репозитория, которые указывают системе, где искать пакеты Docker.

"deb": Это формат репозитория для APT.

[arch=amd64]: Указывает, что репозиторий предназначен для архитектуры amd64 (64-битных систем).

https://download.docker.com/linux/ubuntu: Это URL-адрес репозитория Docker для Ubuntu.

$(lsb_release -cs): Используется для вставки кодового имени (code name) текущей версии Ubuntu. Это кодовое имя версии Ubuntu (в данном случае, focal (20.04LTS), также известное как Focal Fossa). Релизы Ubuntu содержащиеся в Docker репозитории: trusty (14.04LTS), xenial (16.04LTS), bionic (18.04LTS), focal (20.04LTS), jammy (22.04LTS), lunar (23.04), mantic (23.10) и другие минорные версии. Узнать релиз можно командой: lsb_release -a

stable: Это компонент репозитория, который указывает на стабильные версии пакетов.

Таким образом, после выполнения этой команды, система будет знать о новом репозитории Docker и далее сможем устанавливать и обновлять пакеты Docker с использованием apt.

Обновляем список пакетов:

sudo apt update

Получаем информацию о версиях и источниках Docker:

apt-cache policy docker-ce

Вывод должен быть примерно следующим:

docker-ce:
  Installed: (none)
  Candidate: 5:24.0.7-1~ubuntu.20.04~focal
  Version table:
     5:24.0.7-1~ubuntu.20.04~focal 500
        500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
     5:24.0.6-1~ubuntu.20.04~focal 500
        500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
     5:24.0.5-1~ubuntu.20.04~focal 500
        500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

Устанавливает пакет docker-ce:

sudo apt install docker-ce -y

Проверяем статус службы Docker:

sudo systemctl status docker

Вывод сообщает, что служба Docker запущена:

● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-11-21 01:23:44 MSK; 9s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 4686 (dockerd)
      Tasks: 8
     Memory: 26.9M
     CGroup: /system.slice/docker.service
             └─4686 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Разбор вывода

  • Статус службы: Active (running) указывает, что служба работает. Дата и время начала работы службы.
  • Главный процесс (PID) Docker: Это идентификатор процесса, который управляет Docker.
  • Информация о памяти и задачах: Tasks: 8 - количество задач (процессов), связанных со службой Docker. Количество задач может варьироваться в зависимости от активных контейнеров и других процессов, связанных с Docker. Memory: 26.9M - объем оперативной памяти, используемый службой Docker. В данном случае, используется примерно 123.4 мегабайта памяти.
  • Журнал событий: Выводит последние события, связанные с запуском службы.

Эти значения предоставляют информацию о текущем состоянии использования ресурсов службой Docker и могут быть полезными при мониторинге и диагностике работы Docker на вашей системе.

Проверяем корректность установки Docker загрузив контейнер hello-world:

docker run hello-world

Данный вывод свидетельствует о том, что контейнер запустится корректно:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete 
Digest: sha256:c79d06dfdfd3d3eb04cafd0dc2bacab0992ebc243e083cabe208bac4dd7759e0
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

3. Установка Docker Compose

Загружаем последнюю стабильную версию Docker Compose из GitHub:

sudo curl -L "<https://github.com/docker/compose/releases/latest/download/docker-compose-$>(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Разбор команды

$(uname -s) заменяется на имя операционной системы (например, Linux)
$(uname -m) на архитектуру процессора (например, x86_64). Таким образом, формируется URL, который указывает на последнюю версию Docker Compose.

-o /usr/local/bin/docker-compose: Эта часть определяет, куда будет сохранен загруженный файл. В нашем случае, исполняемый файл будет сохранен в /usr/local/bin/ с именем docker-compose

Добавляем права на выполнение:

sudo chmod +x /usr/local/bin/docker-compose

Разбор команды

chmod: Это команда которая изменяет права доступа к файлам.

+x: Дает права на выполнение (execute) для файла. r - чтение (read), w - запись (write)

Чтобы убедиться в успешности установки, выполните следующую команду:

docker-compose --version

Создаем новую сеть в Docker:

docker network create gi01-network

4. Настройка Docker Compose

Переходим в домашний каталог:

cd

Создаем папку:

mkdir ~/compose-gi01

Перейдите в папку:

cd ~/compose-gi01

Создайте файл docker compose:

nano docker-compose.yml

Вставьте в файл следующее содержимое:

version: '3.5'

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    security_opt:
      - no-new-privileges:true
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - portainer-data:/data
    ports:
     - 9000:9000
    networks:
     - gi01-network

volumes:
  portainer-data:
    driver: local

networks:
  gi01-network:
    external: true
    name: gi01-network

Запускаем контейнеры:

docker-compose up -d

-d значит "detach", т.е. отсоединение от терминала

Из вывода видно, что процесс успешно завершен, и контейнер Portainer был создан и запущен.

[+] Running 45/13

 ✔ portainer 11 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                             16.2s 
                                                                                                                          
[+] Building 0.0s (0/0)                                                                                        docker:default
 ✔ Volume "compose-gi01_portainer-data"  Created                                                                         0.0s 
 ✔ Container portainer                   Started                                                                         0.7s 

Для просмотра активных контейнеров используйте команду:

docker ps

Получаем информацию о IP-адресах:

ip a

a значит address

Вывод:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:e8:84:ad brd ff:ff:ff:ff:ff:ff
    inet 1.181.12.98/22 brd 185.117.155.255 scope global ens3
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fee8:84ad/64 scope link 
       valid_lft forever preferred_lft forever

Как видно из вывода мой адрес 1.181.12.98.

Переходим по адресу http://[ваш IP]:9000 и попадаем на страницу Portainer.

Для остановки контейнеров, используйте команду:

docker-compose down

Перезагрузите ОС и проверьте запускаются ли контейнеры:

reboot
docker ps

Если после перезагрузки контейнеры не запустились, автоматизируем данный процесс создав свой сервис systemd для Docker Compose.

5. Создание сервиса systemd

Проверяем где находится исполняемый файл docker-compose:

which docker-compose

Открываем текстовый редактор nano и создаем сервис compose-gi01.service

nano /etc/systemd/system/compose-gi01.service
[Unit]
Description=Docker Compose Gi01
Requires=docker.service
After=docker.service

[Service]
Type=simple
WorkingDirectory=/path/to/your/docker-compose/directory
ExecStart=/path/to/your/docker-compose/service up -d
ExecStop=/path/to/your/docker-compose/service down
TimeoutStartSec=0
Restart=always
RestartSec=30s

[Install]
WantedBy=multi-user.target

У меня: [/path/to/your/docker-compose/directory]: /root/compose-gi01/

[/path/to/your/docker-compose/service]: /usr/local/bin/docker-compose

Перезагружаем демон systemd после внесения изменений:

sudo systemctl daemon-reload

Перезагружаем все Docker контейнеры:

sudo systemctl restart compose-gi01

Убеждаемся в том, что сервис работает и проверяем журнал событий:

systemctl status compose-gi01
sudo journalctl -u compose-gi01

Если все работает правильно добавляем сервис в автозагрузку:

sudo systemctl enable compose-gi01

На этом установка завершена.

В этой статье мы рассмотрели основы оркестрации контейнеров с использованием Docker Compose и интеграции с systemd на Linux. Надеемся, что эта информация поможет вам более эффективно управлять и автоматизировать развертывание ваших приложений. Если у вас есть вопросы или комментарии, не стесняйтесь делиться ими с нами. Удачного вам развертывания контейнеров!