Docker пакує застосунок разом із залежностями в ізольований контейнер, який запускається однаково на будь-якій машині зі встановленим рушієм. На VPS це усуває конфлікти версій PHP чи Node.js між різними проєктами на одному сервері.
Встановлення Docker через офіційний скрипт
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
# Додаємо користувача в групу docker (без sudo)
usermod -aG docker $USER
newgrp docker
Офіційний скрипт сам визначає дистрибутив і підключає потрібний репозиторій — для production переважна явна установка за інструкцією docs.docker.com під конкретну версію Ubuntu чи Debian, щоб зафіксувати пакет, а не отримувати останню версію скриптом при кожному новому сервері.
Встановлення Docker Compose v2
apt install docker-compose-plugin -y
docker compose version
Перший контейнер
# Запуск Nginx у контейнері
docker run -d \
--name mynginx \
-p 80:80 \
-v /var/www/html:/usr/share/nginx/html:ro \
nginx:alpine
# Перевірка
docker ps
curl http://localhost
Основні команди Docker
| Команда | Опис |
|---|---|
| docker ps -a | Усі контейнери |
| docker images | Список образів |
| docker logs -f name | Логи контейнера (live) |
| docker exec -it name bash | Увійти в контейнер |
| docker stats | Використання ресурсів |
| docker system prune | Очищення невикористовуваних даних |
Розбір типових помилок
Помилка docker: permission denied while trying to connect to the Docker daemon socket з'являється, коли користувач не входить у групу docker або зміна групи ще не підхопилася в поточній сесії. Команда newgrp docker або повторний вхід по SSH вирішує проблему без перезавантаження сервера.
docker: Error response from daemon: driver failed programming external connectivity on endpoint mynginx: Bind for 0.0.0.0:80 failed: port is already allocated
Ця помилка означає, що порт 80 на хості вже зайнято — або іншим контейнером, або системним Nginx чи Apache поза Docker. Перевіряється командою ss -tulpn | grep :80 до запуску контейнера, а не після налагодження незрозумілої відмови.
Контейнер завершується одразу після запуску (статус Exited (0) чи з ненульовим кодом) — зазвичай означає, що основний процес усередині контейнера відпрацював і вийшов, а Docker не тримає контейнер живим сам по собі. Причина видна в логах: docker logs mynginx покаже, що саме пішло не так на старті — від відсутнього конфіга до помилки в entrypoint-скрипті.
Docker і файрвол: важлива деталь
Docker прописує власні правила в iptables напряму, в обхід UFW. Опублікований порт контейнера (-p 8080:8080) може лишитися доступним ззовні, навіть якщо в UFW стоїть ufw deny 8080 — правила Docker у ланцюжку DOCKER-USER застосовуються раніше, ніж встигає спрацювати політика UFW. Якщо потрібен контроль доступу до портів контейнерів через файрвол, правила додаються саме в ланцюжок DOCKER-USER, а не через звичайний ufw, — інакше створюється хибне відчуття захищеності, розібране в статті про налаштування UFW на VDS.
Порівняння Docker і звичайного встановлення застосунку
| Параметр | Docker-контейнер | Встановлення напряму на хост |
|---|---|---|
| Ізоляція залежностей | Повна, власні версії бібліотек | Спільна із системою, конфлікти версій можливі |
| Перенесення на інший сервер | Образ переноситься як є | Потрібно повторювати встановлення і налаштування |
| Споживання ресурсів | Невеликий оверхед на рушій | Мінімальне, без прошарку |
| Налагодження на низькому рівні | Складніше, потрібен вхід у контейнер | Прямий доступ до процесів і файлів |
Коли Docker не підходить
- Єдиний застосунок на всьому VPS і без планів масштабування — оверхед на вивчення Docker може не окупитися порівняно з прямим встановленням пакета з репозиторію.
- Застосунку потрібен прямий доступ до пристроїв чи ядра хоста (специфічні драйвери, низькорівнева робота з мережею) — контейнеризація такого вимагає привілейованого режиму, що знижує саму користь ізоляції.
- Команда не готова контролювати файрвол на рівні ланцюжка
DOCKER-USER— інакше публікація портів контейнерів може непомітно відкрити більше, ніж передбачалося в UFW. - Потрібна максимальна продуктивність дискових операцій без прошарку — оверлейна файлова система Docker додає накладні витрати порівняно з прямим записом на хостову ФС.
Перевірка результату
- Перевірте, що демон запускається автоматично:
systemctl is-enabled dockerмає повернутиenabled. - Переконайтеся, що непривілейований користувач може виконувати команди docker без sudo:
docker psвід звичайного користувача не має вимагати пароль чи падати з помилкою доступу. - Перевірте реальну доступність опублікованого порту ззовні, а не лише через
curl http://localhostна самому сервері. - Звірте правила файрволу для портів контейнерів:
iptables -L DOCKER-USER -nпокаже, що реально фільтрується на рівні Docker, окремо від виводуufw status.