Урок 7

Создаём файлы конфигурации Docker

25 мин

Какие файлы нам нужны?

Для настройки Docker нам нужны два файла:

  1. docker-compose.yml — описывает, какие контейнеры запускать и как они связаны
  2. Dockerfile — описывает, как создать наш собственный образ с PHP

Подготовка

Откройте VS Code с папкой my-blog (мы создали её в уроке 0.2).

Создайте такую структуру папок:

my-blog/
├── docker-compose.yml    ← создадим
├── docker/
│   └── Dockerfile        ← создадим
└── public/               ← создадим папку
    └── index.php         ← создадим

Файл docker-compose.yml

В корне папки my-blog создайте файл docker-compose.yml.

Важно: Расширение именно .yml, не .txt! И название точно docker-compose.yml.

Сначала создадим файл .env для хранения настроек (пароли не должны быть в коде!).

Создайте файл .env в корне проекта:

# Настройки базы данных
MYSQL_HOST=mysql
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=blog
MYSQL_USER=blog_user
MYSQL_PASSWORD=blog_pass

# Порты
PHP_PORT=8080
MYSQL_PORT=3306
PHPMYADMIN_PORT=8081
Зачем .env файл?
- Пароли не хранятся в коде (безопасность)
- Легко менять настройки для разных окружений (разработка/продакшн)
- Можно добавить .env в .gitignore (не попадёт в Git)

Теперь скопируйте этот код в docker-compose.yml:

version: "3.8"

services:
  php:
    build:
      context: ./docker
      dockerfile: Dockerfile
    container_name: blog-php
    ports:
      - "${PHP_PORT:-8080}:80"
    volumes:
      - ./public:/var/www/html
    depends_on:
      - mysql
    networks:
      - blog-network

  mysql:
    image: mysql:8.0
    container_name: blog-mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    ports:
      - "${MYSQL_PORT:-3306}:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - blog-network

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: blog-phpmyadmin
    restart: unless-stopped
    ports:
      - "${PHPMYADMIN_PORT:-8081}:80"
    environment:
      PMA_HOST: mysql
      PMA_USER: root
      PMA_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    depends_on:
      - mysql
    networks:
      - blog-network

networks:
  blog-network:
    driver: bridge

volumes:
  mysql_data:

Обратите внимание: ${MYSQL_ROOT_PASSWORD} — это переменная из файла .env. Docker Compose автоматически подставит значение.

Разбор docker-compose.yml построчно

Формат YAML

YAML — это формат файлов, где структура задаётся отступами (пробелами). Это как Python — отступы важны!

version: "3.8"

Версия формата docker-compose. 3.8 — современная и стабильная.

Секция services

services:

Здесь описываются все контейнеры, которые мы хотим запустить.

Контейнер php

  php:                          # Имя сервиса (можете назвать как угодно)
    build:                      # Будем создавать образ из Dockerfile
      context: ./docker         # Папка, где лежит Dockerfile
      dockerfile: Dockerfile    # Имя файла
    container_name: blog-php    # Имя контейнера в Docker
    ports:
      - "8080:80"               # Порт_на_вашем_компе:порт_в_контейнере
    volumes:
      - ./public:/var/www/html  # Папка_на_компе:папка_в_контейнере
    depends_on:
      - mysql                   # Запускать после mysql
    networks:
      - blog-network            # Подключить к сети
Что значит ports: - "8080:80"?

Внутри контейнера Apache работает на порту 80 (стандартный).
Мы пробрасываем его на порт 8080 вашего компьютера.
Поэтому сайт будет доступен по адресу localhost:8080.
Что значит volumes: - ./public:/var/www/html?

Это "монтирование" — связывание папки на вашем компьютере с папкой внутри контейнера.

./public — папка public в вашем проекте
/var/www/html — папка, откуда Apache берёт файлы сайта

Когда вы редактируете файл в public, он сразу меняется и внутри контейнера!

Контейнер mysql

  mysql:
    image: mysql:8.0            # Готовый образ из Docker Hub
    container_name: blog-mysql
    restart: unless-stopped     # Перезапускать, если упал
    environment:                # Переменные окружения
      MYSQL_ROOT_PASSWORD: root123    # Пароль root
      MYSQL_DATABASE: blog            # Создать базу "blog"
      MYSQL_USER: blog_user           # Создать пользователя
      MYSQL_PASSWORD: blog_pass       # Пароль пользователя
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql     # Хранить данные между перезапусками
    networks:
      - blog-network
Про пароли:
В реальном проекте пароли нельзя хранить в коде! Но для обучения это нормально. Главное — не выкладывайте такой файл в публичный репозиторий.

Контейнер phpmyadmin

  phpmyadmin:
    image: phpmyadmin:latest    # Последняя версия
    container_name: blog-phpmyadmin
    restart: unless-stopped
    ports:
      - "8081:80"               # Доступен по localhost:8081
    environment:
      PMA_HOST: mysql           # Имя сервиса MySQL (не localhost!)
      PMA_USER: root
      PMA_PASSWORD: root123
    depends_on:
      - mysql
    networks:
      - blog-network

Сети и volumes

networks:
  blog-network:
    driver: bridge              # Тип сети (стандартный)

volumes:
  mysql_data:                   # Именованный том для данных MySQL

Сеть blog-network позволяет контейнерам общаться друг с другом по именам (mysql, php).

Файл Dockerfile

Создайте папку docker в корне проекта. Внутри создайте файл Dockerfile (без расширения!):

FROM php:8.4-apache

RUN docker-php-ext-install pdo pdo_mysql mysqli

RUN a2enmod rewrite

RUN echo "display_errors = On" >> /usr/local/etc/php/php.ini && \
    echo "error_reporting = E_ALL" >> /usr/local/etc/php/php.ini

WORKDIR /var/www/html

Разбор Dockerfile

FROM php:8.4-apache

FROM — базовый образ. Мы берём готовый образ с PHP 8.4 и Apache. PHP 8.4 — самая новая версия с улучшенной производительностью и новыми возможностями.

RUN docker-php-ext-install pdo pdo_mysql mysqli

RUN — выполнить команду. Устанавливаем расширения PHP для работы с MySQL.

RUN a2enmod rewrite

Включаем модуль mod_rewrite для красивых URL.

RUN echo "display_errors = On" >> /usr/local/etc/php/php.ini

Включаем показ ошибок — удобно для разработки.

WORKDIR /var/www/html

WORKDIR — рабочая директория внутри контейнера.

Файл index.php

Создайте папку public и в ней файл index.php:

<?php
declare(strict_types=1);

echo "<h1>Привет из Docker!</h1>";
echo "<p>PHP версия: " . phpversion() . "</p>";
echo "<p>Сервер: " . $_SERVER["SERVER_SOFTWARE"] . "</p>";
?>
Важно: Мы добавили declare(strict_types=1); в начало файла. Это современная практика PHP 8.4, которая делает код более безопасным и предсказуемым.

Проверяем структуру

У вас должно получиться:

my-blog/
├── .env                    ← файл с настройками (создайте!)
├── docker-compose.yml
├── docker/
│   └── Dockerfile
└── public/
    └── index.php
Не забудьте: Создайте файл .env в корне проекта с настройками из примера выше!
Файлы готовы! В следующем уроке запустим всё это одной командой.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.