Що таке Docker і навіщо він потрібен
Docker — платформа контейнеризації, яка дозволяє упакувати застосунок разом із усіма залежностями в ізольований контейнер. Контейнер однаково запускається на ноутбуці розробника, CI-сервері та production — кінець ері "у мене все працює, а у вас — ні".
Придуманий у 2013 році, сьогодні Docker став стандартом індустрії. 87% DevOps-інженерів використовують його щодня.
Контейнери vs Віртуальні машини
| Характеристика | Контейнери (Docker) | Віртуальні машини |
|---|---|---|
| Час запуску | секунди | хвилини |
| Розмір образу | MB | GB |
| Ізоляція | процесна (ядро OS) | повна (окреме ядро) |
| Споживання RAM | мінімальне | значне |
| Переносимість | висока | середня |
| Безпека | нижча (спільне ядро) | вища |
Контейнери не замінюють ВМ повністю — вони доповнюють їх. Зазвичай на одній ВМ запускають багато контейнерів.
Основи Dockerfile
Dockerfile — текстовий файл з інструкціями для побудови образу. Приклад для Laravel-застосунку:
# Базовий образ
FROM php:8.4-fpm-alpine
# Встановлення залежностей
RUN apk add --no-cache \
git curl libpng-dev libzip-dev \
&& docker-php-ext-install pdo_mysql zip gd
# Встановлення Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Робочий каталог
WORKDIR /var/www
# Копіювання файлів
COPY . .
# Встановлення залежностей PHP
RUN composer install --no-dev --optimize-autoloader
# Права доступу
RUN chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
EXPOSE 9000
CMD ["php-fpm"]Ключові інструкції Dockerfile
FROM— базовий образ (Alpine = легкий Linux)RUN— виконати команду під час побудови образуCOPY— скопіювати файли з хоста в контейнерWORKDIR— встановити робочий каталогEXPOSE— оголосити порт (документація, не публікація)CMD— команда запуску контейнера
Docker Compose: оркестрація локального середовища
docker-compose.yml дозволяє описати всі сервіси проекту та їхні зв'язки в одному файлі.
Реальний приклад: Laravel + MySQL + Redis + Nginx
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/var/www
- ./storage:/var/www/storage
environment:
- DB_HOST=mysql
- DB_DATABASE=laravel
- DB_USERNAME=laravel
- DB_PASSWORD=secret
- REDIS_HOST=redis
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- .:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- app-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
networks:
- app-network
volumes:
mysql-data:
redis-data:
networks:
app-network:
driver: bridgeОсновні команди
# Запустити всі сервіси (фоновий режим)
docker compose up -d
# Зупинити
docker compose down
# Переглянути логи
docker compose logs -f app
# Виконати команду в контейнері
docker compose exec app php artisan migrate
# Перебудувати образ
docker compose build appПереваги Docker для команд
Однакове середовище: junior відтворює production-умови за 5 хвилин замість дня налаштувань
Ізоляція проектів: Python 3.9 для одного і Python 3.12 для іншого — без конфліктів
Швидкий онбординг:
docker compose up -d— і новий розробник готовий до роботиВідтворюваність білдів: образ зібраний сьогодні = образ зібраний через рік
Горизонтальне масштабування:
docker compose up --scale app=3
CI/CD з Docker
Docker ідеально інтегрується з GitHub Actions, GitLab CI, Jenkins:
# .github/workflows/deploy.yml (фрагмент)
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to registry
run: |
docker tag myapp:${{ github.sha }} registry.example.com/myapp:latest
docker push registry.example.com/myapp:latest
- name: Deploy to server
run: |
ssh deploy@server "docker pull registry.example.com/myapp:latest && \
docker compose -f /srv/myapp/docker-compose.prod.yml up -d"Docker Desktop vs Linux
| Docker Desktop (Win/Mac) | Docker на Linux | |
|---|---|---|
| Встановлення | GUI-інсталятор | apt/yum пакет |
| Продуктивність | нижча (гіпервізор) | рідна, без накладних |
| Ціна | безкоштовно для особистого/SMB | безкоштовно |
| Volume binding | повільніше (особливо Mac) | швидко |
| Production | не використовується | стандарт |
Для Windows-розробки альтернатива Docker Desktop — WSL2 + Docker Engine напряму, що дає кращу продуктивність.
Типові помилки початківців
Зберігати дані в контейнері — при перезапуску всі дані зникнуть. Використовуйте volumes.
Запускати все в одному контейнері — один контейнер = один процес. PHP і Nginx — окремо.
Ігнорувати .dockerignore — без нього в образ потрапляють node_modules та .git (сотні MB зайвого).
Використовувати latest тег —
mysql:latestможе зламати проект після оновлення. Фіксуйте версії:mysql:8.0.Зберігати секрети в Dockerfile — паролі та токени передавайте через environment змінні або Docker secrets.
Коли Docker НЕ потрібен
Простий статичний сайт на shared-хостингу
Команда з одного розробника на типовому LAMP стеку
Legacy PHP 5.x проекти — ризик несумісності вищий за вигоду
Embedded-системи з жорсткими обмеженнями ресурсів
Висновок
Docker вирішує реальні проблеми: "працює у мене", різні версії залежностей, складний онбординг, нестабільні деплої. Якщо у вас команда хоча б з двох розробників або ви деплоїте на власний сервер — Docker скупиться на собі за перший місяць.
Потрібна допомога з налаштуванням Docker для вашого проекту? Ми налаштуємо все — від локального dev-середовища до production CI/CD pipeline.