Если вы когда-нибудь пытались настроить окружение для PHP-проекта, то знаете, как это бывает. Сначала всё работает на вашей машине, потом «магически» ломается на сервере. Docker решает эту проблему раз и навсегда. В этой статье я покажу, как быстро и без боли поднять PHP в Docker, даже если вы новичок. Без сложных терминов, с примерами и живыми объяснениями.

Digital-студия WNDER

Почему PHP и Docker — это лучшие друзья?

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

Главная боль любого разработчика — «у меня работает». С Docker эта фраза перестаёт быть шуткой. Вы и ваш коллега получаете одинаковое окружение, даже если у вас Windows, а у него macOS. Это экономит часы времени и нервы.

Ещё один плюс — изоляция. Если у вас на машине стоит PHP 7.4, а проект требует PHP 8.2, не нужно ничего ломать. Просто поднимаете отдельный контейнер с нужной версией. Всё чисто и аккуратно.

С чего начать: базовый Dockerfile для PHP

Для старта вам понадобится Docker, установленный на вашей машине. Если его нет — идите на официальный сайт и ставьте. Это займёт 5 минут, а дальше всё будет просто.

Создайте папку для проекта и положите туда файл Dockerfile. Это инструкция для Docker, как собрать образ. Вот минимальный пример:

FROM php:8.2-cli

WORKDIR /app

COPY . /app

CMD ["php", "-S", "0.0.0.0:8000"]

Разберём по строкам. FROM — базовый образ, здесь мы берём официальный PHP 8.2 CLI. WORKDIR — рабочая папка внутри контейнера. COPY — копирует файлы проекта в контейнер. CMD — команда, которая запустит встроенный сервер PHP для разработки.

Теперь соберите образ и запустите контейнер:

docker build -t my-php-app .
docker run -p 8000:8000 my-php-app

Откройте браузер на localhost:8000 — и ваш PHP работает в контейнере. Поздравляю, вы сделали первый шаг.

Docker Compose: когда проект сложнее

В реальной жизни PHP редко работает сам по себе. Обычно рядом есть MySQL, Nginx, Redis. Управлять каждым контейнером вручную — мука. Для этого придумали Docker Compose. Он позволяет описать все сервисы в одном файле и запускать их одной командой.

Создайте файл docker-compose.yml в корне проекта:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"

Теперь запуск одной командой docker-compose up поднимет и PHP, и MySQL. Обратите внимание на volumes — это синхронизация папок между вашим компьютером и контейнером. Изменяете код — и он сразу подхватывается, без пересборки.

Если нужно остановить всё, просто выполните docker-compose down. Это удобно, когда вы работаете над несколькими проектами одновременно.

Практический пример: PHP + MySQL + Nginx

Теперь соберём полноценный стек. Допустим, у нас есть сайт на PHP, который должен работать через Nginx. Создадим три сервиса: nginx, php и mysql.

Сначала Dockerfile для PHP с нужными расширениями:

FROM php:8.2-fpm

RUN docker-php-ext-install pdo_mysql mysqli

WORKDIR /var/www/html

COPY . /var/www/html

Здесь мы используем образ PHP-FPM, который умеет обрабатывать PHP-запросы, но не отдаёт статику. Для этого нужен Nginx.

Теперь docker-compose.yml:

version: '3.8'

services:
  nginx:
    image: nginx:stable-alpine
    ports:
      - "8080:80"
    volumes:
      - .:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php

  php:
    build: .
    volumes:
      - .:/var/www/html

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app_db
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

И конфиг Nginx (файл nginx.conf):

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

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

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

Запустите docker-compose up --build и откройте localhost:8080. Ваш сайт работает на трёх контейнерах, которые общаются между собой. Это основа любого современного PHP-проекта.

Лайфхаки и типичные ошибки

Теперь несколько советов, которые сэкономят вам кучу времени.

Правило: всегда используйте именованные тома для баз данных. Если вы не укажете volume для MySQL, при пересоздании контейнера все данные будут потеряны. Это как выбросить свой ноутбук с фотографиями — обидно и необратимо.

Частая ошибка — забыть указать depends_on. Без него PHP может запуститься раньше, чем база данных, и упасть с ошибкой соединения. Docker Compose следит за порядком, но лучше указывать явно.

Ещё один момент — права доступа на файлы. Внутри контейнера пользователь может отличаться от вашего. Если видите ошибки записи, добавьте в Dockerfile:

RUN chown -R www-data:www-data /var/www/html

Это даст права веб-серверу на запись в папку проекта.

И не забывайте про .dockerignore — этот файл исключает ненужные папки из образа. Например, vendor или .git. Это ускорит сборку и уменьшит размер образа.

Что в итоге

Docker — это не магия, а просто инструмент. Но он решает реальные проблемы. Вы получаете стабильное окружение, которое можно воспроизвести на любой машине. PHP и Docker отлично дружат, и теперь вы знаете, как их подружить.

Начните с простого — поднимите один контейнер с PHP. Потом добавьте MySQL. Затем Nginx. И вскоре вы будете собирать сложные проекты за пару минут. Главное — практиковаться и не бояться ошибок. Все через это проходили.

Если хотите глубже изучить тему, загляните в документацию Docker и PHP на официальных сайтах. А пока — удачи в ваших экспериментах!

Студия WNDER