Docker и PHP: полное руководство по контейнеризации приложений

Онлайн-тренажер Python для начинающих

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

Начать курс

Docker и PHP: контейнеризация приложений от А до Я

Контейнеризация PHP-приложений с помощью Docker стала стандартом современной веб-разработки. Независимо от того, создаете ли вы простой лендинг или сложное корпоративное приложение, Docker обеспечивает единообразие окружения на всех этапах: от локальной разработки до продакшена. В этой статье мы разберем все этапы создания Docker-инфраструктуры для PHP-приложения — от базового Dockerfile до полноценного стека с Nginx и MySQL.

Почему Docker важен для PHP-разработчика

Традиционная PHP-разработка часто сталкивается с проблемой "на моей машине работает". Разные версии PHP, расширения, настройки сервера — все это приводит к конфликтам. Docker решает эту проблему раз и навсегда:

  • Изоляция окружения — каждое приложение имеет свой набор зависимостей
  • Воспроизводимость — одинаковое окружение на всех машинах
  • Масштабируемость — легко добавлять новые сервисы (Redis, Elasticsearch)
  • CI/CD интеграция — контейнеры идеально подходят для пайплайнов

Давайте перейдем от теории к практике и создадим полноценное Docker-окружение для PHP-приложения.

Создание базового Dockerfile для PHP

Начнем с самого главного — Dockerfile. Это инструкция по сборке образа вашего PHP-приложения. Вот оптимальная конфигурация для production-ready приложения:

# Используем официальный PHP образ с FPM
FROM php:8.2-fpm-alpine

# Установка системных зависимостей
RUN apk add --no-cache \
    git \
    unzip \
    libpq-dev \
    libzip-dev \
    && docker-php-ext-install \
    pdo_mysql \
    zip \
    opcache

# Установка Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Настройка OPcache для продакшена
RUN { \
    echo 'opcache.memory_consumption=128'; \
    echo 'opcache.interned_strings_buffer=8'; \
    echo 'opcache.max_accelerated_files=4000'; \
    echo 'opcache.revalidate_freq=2'; \
    echo 'opcache.fast_shutdown=1'; \
    echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/opcache.ini

# Копируем файлы приложения
WORKDIR /var/www/html
COPY . .

# Устанавливаем права
RUN chown -R www-data:www-data /var/www/html \
    && chmod -R 755 storage bootstrap/cache

# Запускаем PHP-FPM
CMD ["php-fpm"]

EXPOSE 9000

Этот Dockerfile использует Alpine Linux — минимальный образ, который значительно уменьшает размер конечного контейнера. Мы устанавливаем только необходимые расширения: pdo_mysql для работы с базой данных и zip для Composer.

Сборка и запуск контейнера

# Сборка образа
docker build -t my-php-app .

# Запуск контейнера
docker run -d -p 9000:9000 --name php-app my-php-app

Полный стек с Nginx и MySQL через docker-compose

Реальное приложение редко состоит из одного PHP-контейнера. Нам нужен веб-сервер и база данных. Здесь на помощь приходит docker-compose — инструмент для оркестрации нескольких контейнеров.

Создадим файл docker-compose.yml:

version: '3.8'

services:
  # PHP-FPM сервис
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php-app
    volumes:
      - ./:/var/www/html
    networks:
      - app-network

  # Nginx веб-сервер
  nginx:
    image: nginx:alpine
    container_name: php-nginx
    ports:
      - "8080:80"
    volumes:
      - ./:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - app-network

  # MySQL база данных
  db:
    image: mysql:8.0
    container_name: php-mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: app_database
      MYSQL_USER: app_user
      MYSQL_PASSWORD: app_password
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app-network

volumes:
  mysql_data:

networks:
  app-network:
    driver: bridge

Конфигурация Nginx

Создадим файл docker/nginx/default.conf для связки Nginx с PHP-FPM:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

Запуск полного стека

# Запуск всех сервисов
docker-compose up -d

# Просмотр логов
docker-compose logs -f

# Остановка сервисов
docker-compose down

Работа с Composer в контейнере

Управление зависимостями через Composer — неотъемлемая часть PHP-разработки. Docker упрощает этот процесс:

# Установка зависимостей через контейнер
docker run --rm \
    -v $(pwd):/app \
    composer:latest \
    composer install --no-dev --optimize-autoloader

# Запуск artisan команд (для Laravel)
docker exec php-app php artisan migrate
docker exec php-app php artisan cache:clear
docker exec php-app php artisan config:cache

Пример PHP-приложения для теста

Создадим простой скрипт public/index.php для проверки работы стека:

<?php

// Проверка соединения с MySQL
try {
    $pdo = new PDO(
        'mysql:host=db;dbname=app_database',
        'app_user',
        'app_password'
    );
    $connectionStatus = '✅ Подключение к MySQL успешно!';
} catch (PDOException $e) {
    $connectionStatus = '❌ Ошибка подключения: ' . $e->getMessage();
}

// Информация о PHP
$phpVersion = phpversion();
$extensions = get_loaded_extensions();
$requiredExtensions = ['pdo_mysql', 'zip', 'opcache'];
$extensionStatus = [];

foreach ($requiredExtensions as $ext) {
    $extensionStatus[$ext] = in_array($                

Блоги

Рекомендаций по книгам