Всем привет! Постараюсь описать не вдаваясь в сложные термины, как же быстро и без проблем поднять сайт в Docker при помощи docker-compose.
Первый шаг
Для начала нам нужен сам сайт. Предположим, что у нас уже есть некоторый index.php который отдаёт "Hello world" в браузер. Так же предположим, что Docker у вас уже установлен.
Второй шаг: создание файла docker-compose.yml
Контейнеры в Docker - это не виртуальные машины, это просто скорее некоторые выделенные пространства. Нам нужно определиться, какие нам нужны.
Для начала нам должно хватить трёх: первый - это обычный mysql. Второй - это phpmyadmin. Третий - это наше приложение.
Создаём сначала папку db рядом с папкой app, так же следом создаём в корне файл docker-compose.yml.
В папке db mysql сам нашуршит свои файлы баз данных чтобы они не потерялись если вдруг вы будете пересобирать контейнеры. Папка для базы, да.
Структура получается вот такая:
Ну а сам docker-compose.yml такого содержания:
version: '3'
services:
db: #добавляем сюда контейнер с названием db
image: 'mysql:latest' #образ берём последний
environment:
MYSQL_ROOT_PASSWORD: 12345 #здесь нужно обязательно задать пароль для root
command: mysqld --default-authentication-plugin=mysql_native_password
ports:
- '3306:3306' #порт для mysql
volumes:
- './db:/var/lib/mysql' #говорим что папка db проброшена внутрь контейнера и будет использоваться вместо /var/lib/mysql
networks:
- default #говорим, чтобы контейнер использовал дефолтную сеть
phpmyadmin: #контейнер с phpmyadmin
image: phpmyadmin/phpmyadmin
links:
- 'db:db' #делаем линк
ports:
- '8000:80' #сажаем 80 порт ИЗ контейнера на 8000 порт в нашей системе
environment:
PMA_HOST: db #дефолтный хост для базы
PMA_PORT: 3306 #дефолтный порт для базы
app: #наш основной контейнер с сайтом
build: . #билдить надо всё что в нашей папке
ports:
- '80:80' #сажаем 80 порт из контейнера на 80 порт нашего компьютера. Т.е. получается, что мы сможем из браузера по ссылке http://localhost попадать куда надо
volumes:
- './app:/var/www/html/' #говорим, что папка app будет использоваться вместо /var/www/html
restart: always #всегда перезапускать если контейнер упал или закончил работу
links:
- db
networks:
- default
volumes:
persistent: null
Третий шаг: создание Dockerfile
Теперь нам нужно определить, что за контейнер у нас будет и что в нём будет. Для этого мы так же создаём в корне Dockerfile и наполняем его командами для установки nginx и php.
Dockerfile:
FROM ubuntu:20.04 as intermediate
# Выставляем по умолчанию московское время внутри контейнера
RUN ln -snf /usr/share/zoneinfo/"Europe/Moscow" /etc/localtime && echo "Europe/Moscow" > /etc/timezone
# Установка пакетов php и nginx через apt (он используется по умолчанию для ubuntu)
RUN apt-get update \
&& apt-get install -y nginx php7.4 php7.4-cli php7.4-common php7.4-curl php7.4-dev php7.4-mysql php7.4-fpm
# Берём из нашей папки conf (создадим чуть позже) конфиг, который помещаем внутрь и кладём по пути /etc/nginx/sites-available/default
COPY conf/nginx.conf /etc/nginx/sites-available/default
# Нам нужен entrypoint.sh скрипт который будет работать бесконечно и не давать контейнеру заглохнуть
COPY conf/entrypoint.sh /entrypoint.sh
# Так же даём ему немножко прав
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Четвёртый шаг: nginx.conf и entrypoint.sh
Перед тем как создавать эти файлы, нам понадобится папка conf. Структура в итоге выходит вот такая:
В файл entrypoint.sh вешаем запуск php-fpm, nginx и чтение лога.
#!/bin/bash echo "Запускаю nginx & php-fpm" nginx && php-fpm7.4 #Здесь мы вешаем бесконечный просмотр лога nginx который будет показывать ошибки пока контейнер запущен tail -f /var/log/nginx/error.log
Ну а файл nginx.conf заполняем практически стоковой для таких файлов конфигурацией.
server {
listen 80;
listen [::]:80;
server_name localhost;
root /var/www/html/;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
internal;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
Первый запуск
Запускаем
$ docker-compose up в консоли и ждём, пока всё соберётся. :)По завершению можно так же открыть браузер и убедиться, что наш Hello world добрался до нужного места.

Подключение к базе данных
Для проверки подключения к базе данных давайте попробуем модифицировать наш файл index.php в вот такой:
<?php
$host = 'db';
$user = 'root';
$password = '12345';
$database = 'mysql';
// подключаемся к контейнеру db, если не подключится, сработает exit и слов "огонь" мы не увидим
$link = mysqli_connect($host, $user, $password, $database)
or exit("Ошибка " . mysqli_error($link));
echo "Огонь, подключение к базе успешно";
// закрываем подключение
mysqli_close($link);
Проверяем:

