docker Пример докеризации проекта SimpleMVC-example

В данной статье рассмотрим вариант добавления проекта SimpleMVC-example в docker-контейнер.
В сборке применены следующие технологии: PHP-FPM, Nginx, MySQL.
Папка docker расположена в корневой директории проекта и имеет следующую структуру:

docker/
    config/
        mysql/
            create-multiple-mysql-databases.sh
        nginx/
            nginx.conf
        php-fpm/
            docker-php-ext-xdebug.ini
    docker-compose.yml
    Dockerfile

Далее рассмотрим содержимое файлов папки docker и остальных вложенных папок.

docker-compose.yml

version: '3.9'
services:
  nginx:
    image: nginx:alpine
    container_name: smvc-docker_nginx
    ports:
      - 21212:80
    expose:
      - "80"
    environment:
      - VIRTUAL_HOST=smvc.docker.loc
      - VIRTUAL_PORT=80
    volumes:
      - './config/nginx/:/etc/nginx/conf.d/'
      - '..:/var/www'
    depends_on:
      - app
    networks:
      - proxy_network
      - smvc_network

  app:
    build: 
        context: .
        dockerfile: Dockerfile
    container_name: smvc-docker_php
    working_dir: /var/www/
    volumes:
      - '../:/var/www'
      - ./config/php-fpm/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      - db
    networks:
      - smvc_network

  db:
    image: mysql:latest
    container_name: smvc-docker_db
    command: --default-authentication-plugin=mysql_native_password
    volumes:
     - './config/mysql:/docker-entrypoint-initdb.d'
    environment:
      MYSQL_ROOT_PASSWORD: smvc-docker_root
      MYSQL_USER: smvc-docker_user
      MYSQL_PASSWORD: smvc-docker_password
      MYSQL_MULTIPLE_DATABASES: smvc-docker_db,smvc-docker_db_test
    ports:
      - 21222:3306
    networks:
      - smvc_network

networks:
  proxy_network:
    name: nginx_dev_local_network
    external: true
  smvc_network:
    name: smvc_network

Файл с настройками мультиконтейнерной конфигурации, а именно трех контейнеров с префиксами smvc-docker_ в названиях.
В строке 11 параметром VIRTUAL_HOST является локальный домен сайта, который необходимо настроить в файле /etc/hosts на ОС хоста с установленным Docker. Для вышеуказанной конфигурации он должен содержать сроку:

127.0.0.1       smvc.docker.loc

Dockerfile

FROM php:8.3.0-fpm-alpine3.19

RUN apk --no-cache update \
    && apk add --no-cache autoconf g++ make linux-headers \
    \
    && pecl install xdebug-3.3.0 \
    && rm -rf /tmp/pear \
    \
    && docker-php-ext-install pdo_mysql

#composer
ENV COMPOSER_ALLOW_SUPERUSER 1
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www

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

create-multiple-mysql-databases.sh

#!/bin/bash

set -e
set -u

function create_user_and_database() {
	local database=$1
	echo "  Creating database '$database'"
	mysql -u root -p$MYSQL_ROOT_PASSWORD <<-EOSQL
	   CREATE DATABASE \`$database\`;
	   GRANT ALL ON \`$database\`.* TO '$MYSQL_USER'@'%';
EOSQL
}

if [ -n "$MYSQL_MULTIPLE_DATABASES" ]; then
	echo "Multiple database creation requested: $MYSQL_MULTIPLE_DATABASES"
	for db in $(echo $MYSQL_MULTIPLE_DATABASES | tr ',' ' '); do
		create_user_and_database $db
	done
	echo "Multiple databases created"
fi

Скрипт для создания баз данных при первой сборке контейнера. Переменные берутся из docker-compose.yml

nginx.conf

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/web;
    server_name 127.0.0.1 localhost;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_buffers 16 16k; 
        fastcgi_buffer_size 32k;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

Конфигурация Nginx, важной настройкой является строка 6, где указана папка с точкой входа index.php

docker-php-ext-xdebug.ini

zend_extension=xdebug
xdebug.mode=debug
xdebug.client_host=host.docker.internal
xdebug.client_port=9004
xdebug.idekey="netbeans-xdebug"

Является необязательным, служит для настройки расширения Xdebug, при отсутствии необходимости можно удалить (соответственно удалив из Dockerfile и docker-compose.yml).

Вспомогательные "make" команды в Makefile

Makefile

#Задаем подкоманды для изменения цвета
export red=`tput setaf 1`
export green=`tput setaf 2`
export yellow=`tput setaf 3`
export blue=`tput setaf 4`
export magenta=`tput setaf 5`
export cyan=`tput setaf 6`
export white=`tput setaf 7`
export reset=`tput sgr0`

PROJECT_NAME = smvc-docker
APP_CONTANER_COMMAND_PREF_PHP = @docker exec -it $(PROJECT_NAME)_php
APP_CONTANER_COMMAND_PREF_NGINX = @docker exec -it $(PROJECT_NAME)_nginx
APP_CONTANER_COMMAND_PREF_DB = @docker exec -it $(PROJECT_NAME)_db
APP_CONTANER_COMMAND_NO_T_DB = @docker exec -i $(PROJECT_NAME)_db
APP_CONTANER_COMMAND_PROD_PREF = @docker exec -it $(PROJECT_NAME)_web_prod
LOCAL_APP_URL_MESSAGE = @echo  "Локальное приложение  ${cyan}$(PROJECT_NAME)${reset}: http ://localhost:21212"
COMPOSE_DEV = docker compose -f ./docker/docker-compose.yml  --project-name $(PROJECT_NAME)

about:
	@echo "${cyan}Привет!)${reset} Это мэйкфайл для удобной работы с командами ${cyan};)${reset}  \
     \n Выполняйте нужные действия с помощью ${yellow}make имякоманды${reset}, доступные команды: \
     \n ${green}migrate${reset} - применит миграции \
     \n ${green}docker.start.all${reset} - Запустит все контейнеры приложения (соберет образы, если их нет) \
     \n ${green}docker.stop.all${reset} - Остановит все контейнеры приложения \
     \n ${green}docker.restart.all${reset} - Остановит все контейнеры приложения и запустит их заново \
	 \n ${green}docker.rebuild.all${reset} - Остановит все контейнеры приложения, пересоберет их запустит их заново \
	"

# DOCKER---------------------------------------
sh.php:
	$(APP_CONTANER_COMMAND_PREF_PHP) sh -l
sh.nginx:
	$(APP_CONTANER_COMMAND_PREF_NGINX) sh
sh.db:
	$(APP_CONTANER_COMMAND_PREF_DB) sh

docker.start.all:
	$(COMPOSE_DEV)  up -d
	$(LOCAL_APP_URL_MESSAGE)

docker.stop.all:
	$(COMPOSE_DEV)  stop   

docker.rebuild.all: docker.stop.all
	$(COMPOSE_DEV)  up -d --build
	$(LOCAL_APP_URL_MESSAGE)

docker.restart.all: docker.stop.all docker.start.all

docker.remove.db:
	docker rm $(PROJECT_NAME)_db

docker.reset.all: docker.stop.all docker.remove.db docker.rebuild.all

docker.php.sh:
	$(APP_CONTANER_COMMAND_PREF_PHP) sh

#APPLICATION--------------------------------------
composer.install:
	@echo  "Устанавливаем ${yellow}зависимости${reset}..."
	$(APP_CONTANER_COMMAND_PREF_PHP) composer install
grant.assets:
	@echo  "Добавление прав на запись в папку ${green}web/assets${reset}..."
	$(APP_CONTANER_COMMAND_PREF_PHP) chmod o+w web/assets -R
insert.dump:
	$(APP_CONTANER_COMMAND_NO_T_DB) mysql -u $(PROJECT_NAME)_user \
	-p$(PROJECT_NAME)_password $(PROJECT_NAME)_db < input/smvc.sql
	@echo  "Таблицы в базе данных ${yellow}$(PROJECT_NAME)_db${reset} заполнены."

# TMP--------------------------------------------
sh.db.test:
	$(APP_CONTANER_COMMAND_PREF_DB) mysql -u $(PROJECT_NAME)_user -p$(PROJECT_NAME)_password

docker.test.proxy:
	@echo  "${yellow}HTML${reset} содержимое ${green}главной${reset} страницы:"
	@curl -H "Host: smvc.docker.loc" localhost:21212

Файл Makefile служит для упрощения выполнения команд внутри контейнера, должен находиться в корневой директории проекта. Общий синтаксис команды:

make имя_команды

где имя_команды указано в Makefile с начала новой строки до двоеточия.
Примеры команд:

make docker.start.all
make composer.install
make sh.db.test

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

статью лучше разбить на две - первую часть (что уже есть - про докеризацию PHP + Mysql), а вторую уже про SimpleMVC

_____________
матфак вгу и остальная классика =)

руководство для SimpleMVC-example вынесено в отдельную статью SimpleMVC-example Настройка конфигурации для работы в Docker контейнере