Давным-давно в далекой-далекой галактике я пользовался проектом Denwer, удобная сборка (PHP, MySQL, PhpMyAdmin, Apache)
Теперь я пользуюсь Docker и Docker-compose в частности.
Docker технология для создания и управления контейнерами.
- оборачиваем приложение в контейнеры для того, чтобы Docker обеспечивал одинаковое поведение в разных окружениях.
- можно брать Docker контейнеры и запускать их где угодно, где есть Docker. Все поведение будет зафиксировано в контейнере.
- можем сами решать, какую версию приложения использовать внутри контейнера.
- все приложения стоят внутри контейнеров и не засоряют компьютер.
Скачать и установим Docker Desktop (https://www.docker.com/products/docker-desktop/)
github с моей конфигурацией Docker-compose (PHP, MySQL, PhpMyAdmin, Nginx) (https://github.com/komissarovev/docker_php)
Скачиваем проект, запускаем консоль CMD и заходим в папку с проектом.
Запускаем команду
docker-compose build (создаст контейнеры для запуска)
docker-compose up (запустит контейнеры)
Эти команды можно объединить docker-compose up --build
Если добавить флаг -d, то консоль не заблокируется docker-compose up --build -d
Если консоль заблокирована процессом, то процесс можно остановить нажав Ctrl+C
Команда, чтобы остановить процесс выполнения контейнеров docker-compose down
Запустим контейнеры
Получаем вывод статики php на 80-й порт, которая лежит в проекте по пути ./src/public/. Сейчас там один файл index.php и phpMyAdmin на 8000-й порт.
Далее надо настроить базу и пользователя MySQL
В файле docker-compose.yml мы задавали пароль root для MySQL
volume (- mysql_php:/mysql.sql) мы подключаем файл с базой в контейнер, чтобы наша база не разрушалась каждый раз когда мы делаем docker-compose build
mysql:
image: mysql:8.0.29
container_name: tools_php-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=s123123
volumes:
- mysql_php:/mysql.sql
networks:
- tools_php-network
Можно создать базу зайдя в phpMyAdmin под пользователем root, но тогда придется из php тоже подключаться к базе из под root, что не очень хорошо.
Поэтому пойдем другим путем.
В CMD введем команду подключения к запущенному контейнеру docker exec -it tools_php-mysql sh
tools_php-mysql - это имя контейнера, его можно посмотреть в docker-compose.yml -> container_name или ввести команду docker ps - покажет запущенные процессы
Подключимся к контейнеру MySQL
docker exec -it tools_php-mysql sh
Для подключения к самой MySQL внутри контейнера наберем команду
mysql -uroot -p
Пароль задан в файле docker-compose.yml
Создадим базу данных CREATE DATABASE `test`;
Посмотрим на все базы данных SHOW DATABASES;
Создадим пользователя CREATE USER 'user1'@'%' IDENTIFIED BY 's123';
% обозначает что пользователь может подключаться из под любого хоста - это важно т.к. разные контейнеры расположены на разных хостах(ip разные)
Добавим пользователю все права на базу созданную ранее
GRANT ALL PRIVILEGES ON `test` . * TO 'user1'@'%';
Для того чтобы удалить пользователя нужно будет сначала убрать права, а потом удалить.
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user1'@'%';
DROP USER 'user1'@'%';
Теперь можно подключиться новым пользователем к базе через phpMyAdmin.
Имя сервера mysql указано в файле docker-compose.yml.
Дальнейшую настройку базы удобно производить в phpMyAdmin
Посмотрим настройки docker-compose.yml контейнера phpMyAdmin
phpmyadmin:
image: phpmyadmin:latest
container_name: tools_php-phpmyadmin
restart: unless-stopped
environment:
- PMA_ARBITRARY=1
- UPLOAD_LIMIT=1024M
- MEMORY_LIMIT=1024M
- MAX_EXECUTION_TIME=300
ports:
- 8000:80
depends_on:
- mysql
networks:
- tools_php-network
Переменная среды -PMA_ARBITRARY=1 обозначает, что можно подключаться к любому серверу сети, а не только localhost.
-UPLOAD_LIMIT=1024M
-MEMORY_LIMIT=1024M
-MAX_EXECUTION_TIME=300
Этими переменными задается максимальный размер бекапа, который можно загрузить через phpMyAdmin (по умолчанию он очень маленький)
phpMyAdmin запускается в отдельном контейнере с Apache2 на 80 порту, но у нас 80 порт уже занят контейнером с веб-сервером Nginx, который на 80 порту публикует статику PHP.
Поэтому мы перебрасываем 80 порт на 8000 (ports: - 8000:80)
nginx:
image: nginx:stable-alpine
container_name: tools_php-nginx
restart: unless-stopped
ports:
- 80:80
volumes:
- ./src:/var/www
- ./nginx:/etc/nginx/conf.d
depends_on:
- php
networks:
- tools_php-network
В Nginx в первом volume (- ./src:/var/www) подключаем статику сайта с компьютера в контейнер для публикации
Во втором volume (- ./nginx:/etc/nginx/conf.d) настройки самого Nginx для работы с php
server {
listen 80;
index index.php;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
error_page 404 /index.php;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
fastcgi_pass php:9000; - этой строкой Nginx понимает, где расположен сервер с PHP.
Контейнер с PHP по умолчанию расположен на 9000 порту, php - это имя сервиса, которое мы задали в файле docker-compose.yml.
php:
build: ./php
container_name: tools_php-php
environment:
- MYSQL_HOST=mysql
- MYSQL_DATABASE=test_db
- MYSQL_USER=user1
- MYSQL_PASSWORD=s123
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./src:/var/www
depends_on:
- mysql
networks:
- tools_php-network
volume подключаем к контейнеру статику (- ./src:/var/www)
Переменными среды передаем в контейнер настройки MySQL для подключения к базе.
- MYSQL_HOST=mysql
- MYSQL_DATABASE=test_db
- MYSQL_USER=user1
- MYSQL_PASSWORD=s123
В PHP потом их можно взять из глобального массива $_ENV
<?
$connect = mysqli_connect($_ENV["MYSQL_HOST"],$_ENV["MYSQL_USER"],$_ENV["MYSQL_PASSWORD"],$_ENV["MYSQL_DATABASE"]);
if (mysqli_connect_errno()) {
printf("error: %s\n", mysqli_connect_error());
exit();
}
mysqli_query($connect, "SET NAMES utf8");
?>
Еще хочу обратить внимание в файле docker-compose.yml мы подключаем images, из которых будет создан контейнер. Тут можно выбрать версию приложения. Для важных вещей есть смысл указывать точную версию, ну а например phpmyadmin можно брать всегда последнюю версию
nginx:
image: nginx:stable-alpine
mysql:
image: mysql:8.0.29
phpmyadmin:
image: phpmyadmin:latest
Но в сервисе php мы выбрали не image, а путь до файла Dockerfile
php:
build: ./php
Dockerfile (сервиса php)
В php мы уже не просто хотим взять image с версией php:7.4.29-fpm, но и произвести настройку контейнера. Установить службы для работы с MySQL, установить composer и др.
FROM php:7.4.29-fpm
RUN docker-php-ext-install pdo mysqli pdo_mysql
COPY --from=composer /usr/bin/composer /usr/bin/composer
# RUN apt-get update && apt-get install -y \
# git \
# curl \
# zip \
# vim \
# unzip
И последняя команда docker system prune для чистки системы от созданных докером контейнеров, volumes, сетей. Она нужна, если мы закончили работу над проектом и не хотим хранить кучу мусора на компьютере.
Если вам понравилась статья, поставьте плюсик, мне будет приятно)