15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати
08.10.2024

Docker на Ubuntu: Повний посібник з встановлення та використання

Docker — це платформа контейнеризації з відкритим вихідним кодом, яка пакує застосунки та їхні залежності в ізольовані, портативні одиниці, що називаються контейнерами. На відміну від віртуальних машин, контейнери спільно використовують ядро ОС хоста, що робить їх значно легшими, швидшими при запуску та ефективнішими з точки зору ресурсів — критична відмінність для тих, хто запускає навантаження в середовищі VPS Hosting, де обчислювальні ресурси безпосередньо впливають на вартість і продуктивність.

Цей посібник охоплює повний процес встановлення Docker на Ubuntu 20.04, 22.04 та 24.04 LTS, включаючи посилення безпеки після встановлення, робочі процеси Docker Compose та виробничо-релевантні шаблони команд, які більшість посібників не згадує.

Передумови та системні вимоги

Перш ніж виконувати будь-яку команду, перевірте наступне:

  • Версія Ubuntu: 20.04 LTS (Focal), 22.04 LTS (Jammy) або 24.04 LTS (Noble). Команда `lsb_release -cs`, що використовується під час налаштування репозиторію, автоматично визначить вашу кодову назву.
  • Архітектура: `amd64`, `arm64` або `armhf` — усі підтримуються офіційним репозиторієм Docker.
  • Версія ядра: Docker вимагає ядро Linux 3.10 або вище. Виконайте `uname -r` для підтвердження.
  • Привілеї користувача: `sudo` або root-доступ є обов’язковими для встановлення та керування демоном.
  • Дисковий простір: Щонайменше 2 GB вільного місця на розділі, де розміщено `/var/lib/docker`, — саме там Docker зберігає образи, контейнери, томи та кеш збірки. На виробничих системах змонтуйте цей каталог на окремому розділі або томі.

Критичний крок перед встановленням: Якщо ви раніше встановлювали Docker із стандартного репозиторію `apt` Ubuntu (пакет `docker.io`), спочатку видаліть його, щоб уникнути конфліктів з офіційними пакетами Docker CE:

“`bash

sudo apt remove docker docker-engine docker.io containerd runc

“`

Крок 1: Оновлення системних пакетів

Оновіть індекс пакетів та встановлені пакети до останніх версій перед додаванням будь-якого нового репозиторію:

“`bash

sudo apt update

sudo apt upgrade -y

“`

Це гарантує, що резолвер залежностей `apt` працює з актуальними метаданими пакетів і що базові системні бібліотеки не застаріли — поширене джерело непомітних помилок виконання в контейнеризованих застосунках.

Крок 2: Встановлення Docker Engine з офіційного репозиторію

Стандартні репозиторії `apt` Ubuntu містять пакет `docker.io`, який підтримується Canonical і зазвичай відстає на кілька версій від офіційного релізу Docker. Для виробничого використання завжди встановлюйте з власного репозиторію Docker.

2.1 Встановлення транспорту та залежностей для перевірки

“`bash

sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release -y

“`

Навіщо `gnupg`? Починаючи з Ubuntu 22.04, `gpg` не завжди присутній за замовчуванням. Явне його включення запобігає тихому збою імпорту GPG-ключа.

2.2 Додавання офіційного GPG-ключа Docker

“`bash

sudo install -m 0755 -d /usr/share/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

sudo chmod a+r /usr/share/keyrings/docker-archive-keyring.gpg

“`

Крок `chmod a+r` часто пропускається в посібниках, але є необхідним на системах, де `apt` працює в контексті обмеженого користувача — без нього менеджер пакетів не може прочитати keyring і видасть помилку `NO_PUBKEY` під час `apt update`.

2.3 Додавання стабільного репозиторію Docker

“`bash

echo

"deb [arch=$(dpkg –print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]

https://download.docker.com/linux/ubuntu

$(lsb_release -cs) stable" |

sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

“`

Підстановка `arch=$(dpkg –print-architecture)` є необхідною на ARM-серверах. Жорстке кодування `amd64` тут — поширена помилка, яка призводить до тихих збоїв розв’язання пакетів на ARM-інстансах.

2.4 Встановлення Docker Engine, CLI та плагінів

“`bash

sudo apt update

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

“`

Опис пакетів:

ПакетРоль
`docker-ce`Демон Docker Engine (`dockerd`)
`docker-ce-cli`Клієнтський CLI (команда `docker`)
`containerd.io`Низькорівневе середовище виконання контейнерів (сумісне з OCI)
`docker-buildx-plugin`Розширені можливості збірки (мультиплатформенність, BuildKit)
`docker-compose-plugin`Compose V2, інтегрований як плагін Docker CLI

Примітка щодо `containerd.io`: Це не те саме, що пакет `containerd` у стандартному репозиторії Ubuntu. `containerd.io` від Docker — це конкретна, протестована версія середовища виконання containerd. Змішування двох є відомим джерелом збоїв запуску демона.

Крок 3: Перевірка встановлення

Підтвердіть, що демон активний і налаштований на запуск при завантаженні:

“`bash

sudo systemctl status docker

sudo systemctl enable docker

“`

Перевірте встановлену версію:

“`bash

sudo docker –version

sudo docker info

“`

`docker info` є більш інформативним, ніж `–version` окремо — він показує драйвер сховища (зазвичай `overlay2`), драйвер cgroup (`systemd` проти `cgroupfs`), а також кількість CPU та обсяг пам’яті, до яких Docker має доступ.

Запустіть канонічний димовий тест:

“`bash

sudo docker run hello-world

“`

Успішний запуск виводить повідомлення «Hello from Docker!» і підтверджує, що демон Docker, завантаження образу з Docker Hub та виконання контейнера — все працює коректно.

Крок 4: Налаштування Docker для доступу без root

За замовчуванням сокет Docker (`/var/run/docker.sock`) належить `root` та групі `docker`. Будь-який користувач, що не входить до групи `docker`, повинен використовувати `sudo` для кожної команди Docker.

“`bash

sudo usermod -aG docker $USER

“`

Застосуйте членство в групі без виходу із системи:

“`bash

newgrp docker

“`

Перевірте:

“`bash

docker run hello-world

“`

Попередження щодо безпеки: Членство в групі `docker` фактично еквівалентне `sudo` без пароля. Користувач у групі `docker` може легко змонтувати файлову систему хоста в контейнер і обійти всі засоби контролю доступу на рівні файлової системи. На багатокористувацьких системах або спільних серверах розгляньте використання rootless Docker натомість:

“`bash

dockerd-rootless-setuptool.sh install

“`

Режим rootless запускає демон Docker і контейнери в непривілейованому просторі імен користувача, що значно зменшує поверхню атаки. Це рекомендована конфігурація для будь-якого середовища, де кілька користувачів спільно використовують один хост.

Крок 5: Довідник основних команд Docker

Керування образами

“`bash

Pull a specific image version from Docker Hub

docker pull nginx:1.27-alpine

List locally cached images

docker images

Remove a specific image

docker rmi nginx:1.27-alpine

Remove all dangling (untagged) images to reclaim disk space

docker image prune

Remove all unused images (not just dangling)

docker image prune -a

“`

Порада для виробництва: Завжди завантажуйте теговані версії (наприклад, `nginx:1.27-alpine`), а не `latest` в будь-якому автоматизованому або виробничому робочому процесі. Тег `latest` є змінним — він може вказувати на інший образ після публікації в реєстрі, порушуючи відтворюваність.

Життєвий цикл контейнера

“`bash

Run a container interactively with a pseudo-TTY

docker run -it ubuntu:22.04 /bin/bash

Run a container in detached mode with port mapping and a name

docker run -d -p 8080:80 –name my-nginx nginx:1.27-alpine

List running containers

docker ps

List all containers (including stopped)

docker ps -a

Stop a running container gracefully (SIGTERM, then SIGKILL after timeout)

docker stop my-nginx

Start a stopped container

docker start my-nginx

Remove a stopped container

docker rm my-nginx

Force-remove a running container (sends SIGKILL immediately)

docker rm -f my-nginx

View real-time logs

docker logs -f my-nginx

Execute a command inside a running container

docker exec -it my-nginx /bin/sh

“`

Перевірка ресурсів та системи

“`bash

Display real-time resource usage statistics

docker stats

Inspect detailed container metadata (JSON)

docker inspect my-nginx

Display disk usage by Docker objects

docker system df

Remove all stopped containers, unused networks, dangling images, and build cache

docker system prune

“`

`docker system prune` є однією з найважливіших команд обслуговування для серверів, що працюють тривалий час. Без періодичного очищення кеш збірки Docker і зупинені контейнери можуть займати десятки гігабайт на активному хості розробки або CI.

Крок 6: Docker Compose — оркестрація багатоконтейнерних застосунків

Docker Compose V2 (`docker-compose-plugin`, встановлений раніше) викликається як `docker compose` (з пробілом), а не застарілий `docker-compose` (з дефісом). Обидва синтаксиси працюють, якщо у вас встановлено плагін, але V2 є поточним стандартом.

6.1 Розуміння структури файлу Compose

Створіть каталог проєкту та файл `compose.yml` (бажана назва файлу в Compose V2; `docker-compose.yml` залишається підтримуваним для зворотної сумісності):

“`bash

mkdir ~/my-web-app && cd ~/my-web-app

nano compose.yml

“`

Виробничо-реалістичний приклад з Nginx та бекенд-сервісом:

“`yaml

services:

web:

image: nginx:1.27-alpine

ports:

  • "8080:80"

volumes:

  • ./nginx.conf:/etc/nginx/nginx.conf:ro
  • ./html:/usr/share/nginx/html:ro

depends_on:

  • app

restart: unless-stopped

app:

image: node:20-alpine

working_dir: /usr/src/app

volumes:

  • ./app:/usr/src/app

command: node server.js

environment:

  • NODE_ENV=production

restart: unless-stopped

“`

Пояснення ключових директив Compose:

  • `restart: unless-stopped` — Контейнер автоматично перезапускається після збою або перезавантаження системи, якщо він не був явно зупинений оператором. Це правильна політика для довготривалих сервісів; `always` перезапускатиме навіть навмисно зупинені контейнери.
  • `depends_on` — Контролює порядок запуску, але не чекає, поки сервіс буде *готовий* (наприклад, база даних приймає з’єднання). Для перевірки готовності використовуйте `healthcheck` у поєднанні з `condition: service_healthy`.
  • `volumes` з `:ro` — Монтування файлів конфігурації як тільки для читання запобігає зміні скомпрометованим процесом контейнера власної конфігурації.

6.2 Команди робочого процесу Compose

“`bash

Start all services in detached mode

docker compose up -d

View logs for all services

docker compose logs -f

View logs for a specific service

docker compose logs -f web

List running Compose services

docker compose ps

Scale a specific service to multiple replicas

docker compose up -d –scale app=3

Stop services without removing containers

docker compose stop

Stop and remove containers, networks, and volumes

docker compose down –volumes

Rebuild images before starting (useful after code changes)

docker compose up -d –build

“`

6.3 Перевірка запущеного сервісу

“`bash

curl -I http://localhost:8080

“`

Відповідь `200 OK` підтверджує, що Nginx обслуговує коректно. Для сервісів, що працюють на віддаленому екземплярі VPS Hosting, замініть `localhost` на публічну IP-адресу вашого сервера та переконайтеся, що відповідний порт відкритий у вашому брандмауері (`ufw allow 8080/tcp`).

Крок 7: Основи мережі Docker

Розуміння мережевої моделі Docker є необхідним для побудови багатоконтейнерних застосунків, які безпечно взаємодіють.

Стандартні мережеві драйвери:

ДрайверВипадок використання
`bridge`За замовчуванням для автономних контейнерів; ізольований мережевий простір імен на хості
`host`Контейнер спільно використовує мережевий стек хоста; максимальна продуктивність, нульова ізоляція
`none`Без мережевого доступу; корисно для пакетної обробки або навантажень з підвищеними вимогами до безпеки
`overlay`Багатохостова мережа для кластерів Docker Swarm
`macvlan`Призначає MAC-адресу контейнеру; відображається як фізичний пристрій у мережі

Створення та використання власної bridge-мережі:

“`bash

Create an isolated network

docker network create my-app-network

Run containers attached to the custom network

docker run -d –name db –network my-app-network postgres:16-alpine

docker run -d –name api –network my-app-network my-api-image

Containers on the same custom bridge network can resolve each other by name

Inside 'api', you can connect to 'db' using the hostname 'db'

“`

Власні bridge-мережі забезпечують автоматичне DNS-розв’язання між контейнерами за іменем контейнера. Стандартна мережа `bridge` — ні. Це критична відмінність, яка призводить до збоїв з’єднання, коли розробники припускають, що контейнери в стандартній мережі можуть звертатися один до одного за іменем.

Крок 8: Постійні дані з томами Docker

Контейнери є ефемерними за своєю природою. Будь-які дані, записані у файлову систему контейнера, втрачаються при його видаленні. Для постійного зберігання використовуйте томи або bind-монтування.

“`bash

Create a named volume

docker volume create pgdata

Use the volume with a container

docker run -d

–name postgres-db

-e POSTGRES_PASSWORD=securepassword

-v pgdata:/var/lib/postgresql/data

postgres:16-alpine

List volumes

docker volume ls

Inspect a volume (shows mount point on host)

docker volume inspect pgdata

Remove unused volumes

docker volume prune

“`

Томи проти bind-монтувань:

ФункціяІменований томBind-монтування
Керується DockerТакНі
Потрібен шлях хостаНіТак
Портативність між хостамиТак (з драйверами томів)Ні
Найкраще дляДаних бази даних, стану застосункуКоду розробки, файлів конфігурації
Механізм резервного копіювання`docker run –volumes-from`Стандартні інструменти файлової системи

Крок 9: Підтримання Docker в актуальному стані

Офіційний репозиторій Docker обробляє оновлення через стандартний механізм `apt`:

“`bash

sudo apt update

sudo apt upgrade -y

“`

Щоб оновити лише пакети, пов’язані з Docker, без оновлення всієї системи:

“`bash

sudo apt install –only-upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

“`

Перевіряйте примітки до релізів Docker перед оновленнями основних версій, особливо щодо змін у драйвері сховища, обробці версій cgroup або застарілих версіях API, які можуть вплинути на існуючі файли `compose.yml`.

Docker проти альтернативних підходів до контейнеризації

ФункціяDocker EnginePodmanLXC/LXDcontainerd (автономний)
Архітектура демонаЦентралізований демонБез демонаНа основі демонаНа основі демона
Підтримка rootlessТак (v20+)НативнаОбмеженаТак
Підтримка Docker ComposeНативнаЧерез `podman-compose`НіНі
Відповідність OCIТакТакНі (формат LXC)Так
Інтеграція з KubernetesЧерез CRI-dockerd shimНативний CRIНіНативний CRI
Підтримка Windows/macOSDocker DesktopОбмеженаНіНі
Найкраще підходить дляЗагальної розробки та виробництваОрієнтованих на безпеку, rootlessСистемних контейнерів, VMВузлів Kubernetes

Для команд, що запускають контейнеризовані навантаження у масштабі на bare metal, середовище Dedicated Servers надає повний контроль над параметрами ядра, плануванням вводу-виводу сховища та конфігурацією мережі — все це безпосередньо впливає на щільність контейнерів і продуктивність.

Контрольний список посилення безпеки для виробництва

Перш ніж запускати Docker у виробничому середовищі, вирішіть наступне:

Конфігурація демона (`/etc/docker/daemon.json`):

“`json

{

"log-driver": "json-file",

"log-opts": {

"max-size": "10m",

"max-file": "3"

},

"storage-driver": "overlay2",

"userns-remap": "default",

"live-restore": true,

"no-new-privileges": true

}

“`

  • `log-opts` з `max-size` та `max-file`: Без ротації логів JSON-файли логів Docker заповнять ваш диск. Це одна з найпоширеніших причин несподіваних збоїв сервера на контейнеризованих хостах.
  • `userns-remap: "default"`: Вмикає перемаппінг простору імен користувачів, тому root контейнера (UID 0) відображається на непривілейований UID на хості.
  • `live-restore: true`: Дозволяє контейнерам продовжувати роботу, якщо демон Docker аварійно завершується або перезапускається під час оновлення — критично для обслуговування без простоїв.
  • `no-new-privileges: true`: Запобігає отриманню процесами контейнера додаткових привілеїв через бінарні файли `setuid` або `setgid`.

Міркування щодо мережі та брандмауера:

Docker безпосередньо маніпулює `iptables` і за замовчуванням обходить правила `ufw`. Контейнер з опублікованим портом (`-p 8080:80`) буде доступний з інтернету, навіть якщо `ufw deny 8080` встановлено. Щоб застосувати правила `ufw` поверх маніпуляцій Docker з `iptables`, додайте `"iptables": false` до `daemon.json` та керуйте маршрутизацією вручну, або використовуйте `–network host` Docker з явними правилами `ufw`.

Для проєктів, що потребують завершення HTTPS, поєднайте ваш контейнеризований застосунок з належно налаштованим зворотним проксі (Nginx або Traefik) та дійсним сертифікатом. SSL Certificates є обов’язковою умовою для будь-якого виробничого веб-сервісу, що працює за контейнеризованим стеком.

Якщо ваше навантаження включає інференс машинного навчання, обслуговування моделей або GPU-прискорену обробку даних всередині контейнерів, NVIDIA Container Toolkit інтегрується безпосередньо з Docker Engine. GPU Hosting забезпечує необхідне апаратне забезпечення для цих навантажень.

Для команд, що керують кількома проєктами з веб-інтерфейсом керування контейнерами, VPS with cPanel пропонує середовище керованої панелі управління, яке може доповнити розгортання на основі Docker для простіших стеків застосунків.

Ключові технічні висновки та матриця рішень

Коли використовувати Docker на VPS проти виділеного сервера:

  • Використовуйте VPS для середовищ розробки, стейджингу та виробничих навантажень з низьким і середнім трафіком, де щільність контейнерів становить 10–50 контейнерів.
  • Використовуйте виділений сервер, коли щільність контейнерів перевищує 50 екземплярів, коли потрібна передбачувана продуктивність вводу-виводу (без ефекту галасливого сусіда), або коли для вашого навантаження потрібне налаштування параметрів ядра (`sysctl`).

Операційний контрольний список перед запуском у виробництво:

  • Налаштуйте ротацію логів у `daemon.json` (`max-size`, `max-file`)
  • Увімкніть `live-restore` для виживання після перезапуску демона без простою контейнерів
  • Використовуйте іменовані томи, а не bind-монтування, для даних сервісів зі станом
  • Закріплюйте версії образів у всіх файлах `compose.yml` — ніколи не використовуйте `latest` у виробництві
  • Увімкніть `userns-remap` або запускайте rootless Docker на багатокористувацьких хостах
  • Перевіряйте правила `iptables` після встановлення Docker, щоб переконатися, що політика брандмауера не обходиться
  • Встановіть `restart: unless-stopped` для всіх довготривалих сервісів
  • Запускайте `docker system prune` за розкладом cron для запобігання вичерпанню диска
  • Використовуйте власні bridge-мережі для всієї міжконтейнерної комунікації — ніколи не покладайтеся на стандартний bridge для виявлення сервісів

FAQ

Чи використовує Docker на Ubuntu `systemd` або `cgroupfs` як драйвер cgroup за замовчуванням?

Починаючи з Docker Engine 20.10, стандартним драйвером cgroup на системах на основі `systemd` (включаючи всі сучасні релізи Ubuntu LTS) є `systemd`. Це відповідає вимогам Kubernetes і дозволяє уникнути нестабільності, спричиненої одночасним запуском двох менеджерів cgroup. Ви можете перевірити це за допомогою `docker info | grep -i cgroup`.

У чому різниця між `docker compose down` та `docker compose stop`?

`docker compose stop` зупиняє запущені контейнери, але зберігає їх разом з пов’язаними мережами. `docker compose down` зупиняє контейнери, а потім видаляє їх разом з мережами, створеними Compose. Додавання `–volumes` до `down` також видаляє іменовані томи, визначені у файлі Compose — використовуйте цей прапор з обережністю у виробництві, оскільки він безповоротно видаляє постійні дані.

Чому Docker обходить правила брандмауера `ufw` на Ubuntu?

Docker вставляє власні правила `iptables` у ланцюжки `DOCKER` та `DOCKER-USER`, які обробляються до правил ланцюжка `INPUT` `ufw`. Це означає, що порт, опублікований за допомогою `-p`, доступний з інтернету незалежно від політики `ufw`. Правильним способом усунення є безпосереднє додавання правил до ланцюжка `DOCKER-USER` або прив’язка опублікованих портів до конкретного інтерфейсу (наприклад, `-p 127.0.0.1:8080:80`), коли зовнішній доступ не потрібен.

Як обмежити CPU та пам’ять, які може споживати контейнер Docker?

Використовуйте прапори обмеження ресурсів під час виконання: `docker run –memory="512m" –cpus="1.5" my-image`. У Compose встановіть їх під ключем `deploy.resources` (Compose V2) або ключами верхнього рівня `mem_limit` та `cpus`. Без обмежень один некерований контейнер може вичерпати ресурси хоста і вивести з ладу всі інші контейнери на тому самому хості.

Чи можна запускати Docker всередині контейнера Docker (Docker-in-Docker)?

Так, але це категорично не рекомендується для виробничого використання. Поширений шаблон для CI-конвеєрів — монтування сокета Docker хоста (`-v /var/run/docker.sock:/var/run/docker.sock`) у CI-контейнер, що надає контейнеру повний контроль над демоном Docker хоста — значний ризик безпеки. Безпечнішою альтернативою є використання прапора `–allow security.insecure` BuildKit або спеціалізованих інструментів, таких як Kaniko або Buildah, які збирають OCI-образи без необхідності в демоні Docker.

15%

Збережіть 15% на всі хостинг-послуги

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код:

Skills
Почати