15%

Спести 15% на всички хостинг услуги

Тествай уменията си и получи Отстъпка за всеки хостинг план

Използвайте код:

Skills
За начало
08.10.2024

Docker на Ubuntu: Пълно ръководство за инсталиране и използване

Docker е платформа за контейнеризация с отворен код, която пакетира приложения и техните зависимости в изолирани, преносими единици, наречени контейнери. За разлика от виртуалните машини, контейнерите споделят ядрото на хост операционната система, което ги прави значително по-леки, по-бързи за стартиране и по-ефективни по отношение на ресурсите — критично разграничение за всеки, който изпълнява натоварвания в среда за VPS Хостинг, където изчислителните ресурси пряко влияят върху разходите и производителността.

Това ръководство обхваща пълния процес на инсталиране на 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` работи в контекст на ограничен потребител — без нея мениджърът на пакети не може да прочете ключодържателя и ще генерира грешка `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

“`

Режимът без root права изпълнява демона на 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 Хостинг инстанс, заменете `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 (самостоятелен)
Архитектура на демонаЦентрализиран демонБез демонБазиран на демонБазиран на демон
Поддръжка без root праваДа (v20+)ВграденаОграниченаДа
Поддръжка на Docker ComposeВграденаЧрез `podman-compose`НеНе
OCI съответствиеДаДаНе (LXC формат)Да
Интеграция с KubernetesЧрез CRI-dockerd shimВграден CRIНеВграден CRI
Поддръжка на Windows/macOSDocker DesktopОграниченаНеНе
Най-подходящ заОбща разработка и производствоФокусиран върху сигурността, без root праваСистемни контейнери, виртуални машиниKubernetes възли

За екипи, изпълняващи контейнеризирани натоварвания в мащаб на bare metal, средата Dedicated Servers ви дава пълен контрол върху параметрите на ядрото, планирането на I/O за съхранение и мрежовата конфигурация — всички от които пряко влияят върху плътността на контейнерите и производителността.

Контролен списък за укрепване на производствената среда

Преди да стартирате 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` над манипулацията на `iptables` от Docker, добавете `"iptables": false` към `daemon.json` и управлявайте маршрутизирането ръчно, или използвайте `–network host` на Docker с изрични правила `ufw`.

За проекти, изискващи HTTPS терминиране, сдвоете контейнеризираното си приложение с правилно конфигуриран обратен прокси (Nginx или Traefik) и валиден сертификат. SSL Сертификатите са предпоставка за всяка производствена уеб услуга, работеща зад контейнеризиран стек.

Ако вашето натоварване включва извод за машинно обучение, обслужване на модели или GPU-ускорена обработка на данни в контейнери, NVIDIA Container Toolkit се интегрира директно с Docker Engine. GPU Хостингът осигурява необходимия хардуер за тези натоварвания.

За екипи, управляващи множество проекти с уеб-базирано управление на контейнери, VPS с cPanel предлага управлявана среда с контролен панел, която може да допълни базираните на Docker внедрявания за по-прости стекове от приложения.

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

Кога да използвате Docker на VPS срещу dedicated сървър:

  • Използвайте VPS за среди за разработка, тестване и производствени натоварвания с ниско до средно натоварване, където плътността на контейнерите е 10–50 контейнера.
  • Използвайте dedicated сървър, когато плътността на контейнерите надвишава 50 инстанции, когато се нуждаете от предвидима I/O производителност (без ефект на шумен съсед) или когато настройката на параметрите на ядрото (`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 мрежата по подразбиране за откриване на услуги

Често задавани въпроси

Използва ли 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
За начало