docker web server nginx php mysql
Docker Nginx + PHP + MySQL
Docker Nginx + PHP + MySQL
Теперь создадим связку Nginx + PHP ( пока без MySQL )
Создадим конфиг для nginx:
Создадим файлы для логов nginx:
touch /data/web/logs/nginx-error.log
touch /data/web/logs/nginx-access.log
Создадим тестовый файл php:
» > /data/web/public/index.php» />
Создадим compose файл для объединения образов nginx и php:
Образ nginx использует образы с именами tutum/nginx и линковку на образ php-fpm:
tutum/nginx
php-fpm
Пробрасываем файлы, инча после каждого перезапуска контейнера все будет очищаться
Т.е. из каталога на машине с докером мы пробрасываем папку веб-проекта в контейнер
Проверяем:
docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
97d8b54f1145 tutum/nginx «/usr/sbin/nginx» Up 2 minutes 0.0.0.0:80->80/tcp web_nginx_1
401891b69b07 php:fpm «docker-php-entrypoi…» Up 2 minutes 0.0.0.0:9000->9000/tcp, 9000/tcp web_php-fpm_1
Если какой-либо из контейнеров не запускается, смотрим логи:
docker logs 97d8b54f1145
Столкнулся с проблемой, которую так и не понял, как решить толком, как сделал
Если столкнетесь с ошибкой:
nginx: [emerg] invalid number of arguments in «fastcgi_param» directive in /etc/nginx/sites-enabled/default:11
Управление проектом compose:
docker-compose stop
docker-compose start
Теперь добавим MySQL
Дополним compose файл:
Еще нам нужно установить драйверы для php для подключения к MySQL
Это делается в Dockerfile (Поэтому мы убрали image)
Проверяем:
docker ps
CONTAINER ID IMAGE COMMAND PORTS NAMES
06638849b713 tutum/nginx «/usr/sbin/nginx» 0.0.0.0:80->80/tcp web_nginx_1
b840c2388b81 web_php-fpm «docker-php-entrypoi…» 0.0.0.0:9000->9000/tcp web_php-fpm_1
c2de120b6e7f mysql:8.0 «docker-entrypoint.s…» 0.0.0.0:3306->3306/tcp, 33060/tcp web_mysql_1
Выбираем базу данных из файла docker-compose.yml:
show databases;
+———————+
| Database |
+———————+
| dbname |
| information_schema |
| mysql |
| performance_schema |
| sys |
+———————+
Создаем тестовые данные:
CREATE TABLE test
(
id INT NOT NULL auto_increment,
name VARCHAR(30) NOT NULL DEFAULT »,
PRIMARY KEY (id)
);
INSERT INTO test (name) VALUES («testname1»);
INSERT INTO test (name) VALUES («testname2»);
INSERT INTO test (name) VALUES («testname3»);
А эта строка, чтоб не вылезла ошибка
Uncaught PDOException: PDO::__construct():
The server requested authentication method unknown to the client [caching_sha2_password]:
alter user ‘root’@’%’ identified with mysql_native_password by ‘32167’;
Настройка веб-сервера в Docker (NGINX + PHP + MariaDB)
По данной инструкции мы настроим наш веб сервер в Docker следующим образом:
Данную конфигурацию можно использовать для быстрого развертывания сайтов или для локальной разработки.
Мы будем работать в системе на базе Linux. Предполагается, что Docker уже установлен.
NGINX + PHP + PHP-FPM
Рекомендуется каждый микросервис помещать в свой отдельный контейнер, но мы (для отдельного примера) веб-сервер с интерпретатором PHP поместим в один и тот же имидж, на основе которого будут создаваться контейнеры.
Создание образа
Создадим каталог, в котором будут находиться файлы для сборки образа веб-сервера:
Переходим в созданный каталог:
* где:
1) указываем, какой берем базовый образ. В нашем случае, CentOS 8.
3) задаем для информации того, кто создал образ. Указываем свое имя и адрес электронной почты.
5) создаем переменную окружения TZ с указанием временной зоны (в нашем примере, московское время).
7) запускаем обновление системы.
8) устанавливаем пакеты: веб-сервер nginx, интерпретатор php, сервис php-fpm для обработки скриптов, модуль php-mysqli для работы php с СУБД MySQL/MariaDB.
9) удаляем скачанные пакеты и временные файлы, образовавшиеся во время установки.
10) добавляем в конфигурационный файл nginx строку daemon off, которая запретит веб-серверу автоматически запуститься в качестве демона.
11) создаем каталог /run/php-fpm — без него не сможет запуститься php-fpm.
13) копируем содержимое каталога html, который находится в том же каталоге, что и dockerfile, в каталог /usr/share/nginx/html/ внутри контейнера. В данной папке должен быть наше веб-приложение.
15) запускаем php-fpm и nginx. Команда CMD в dockerfile может быть только одна.
17) открываем порт 80 для работы веб-сервера.
В рабочем каталоге создаем папку html:
. а в ней — файл index.php:
* мы создали скрипт, который будет выводить информацию о php в браузере для примера. По идее, в данную папку мы должны положить сайт (веб-приложение).
Создаем первый билд для нашего образа:
Новый образ должен появиться в системе:
При желании, его можно отправить на Docker Hub следующими командами:
docker tag dmosk/webapp:v1 dmosk/web:nginx_php7
docker push dmosk/web:nginx_php7
* первой командой мы прошли аутентификацию на портале докер-хаба (в качестве id/login мы используем dmosk — это учетная запись, которую мы зарегистрировали в Docker Hub). Вторая команда создает тег для нашего образа, где dmosk — учетная запись на dockerhub; web — имя репозитория; nginx_php7 — сам тег. Последняя команда заливает образ в репозиторий.
* подробнее про загрузку образа в репозиторий докера.
Запуск контейнера и проверка работы
Запускаем веб-сервер из созданного образа:
Открываем браузер и переходим по адресу http:// — откроется страница phpinfo:
Наш веб-сервер из Docker работает.
MariaDB
Для запуска СУБД мы будем использовать готовый образ mariadb. Так как после остановки контейнера, все данные внутри него удаляются, мы должны подключить внешний том, на котором будут храниться наши базы.
Сначала создаем том для докера:
* в данном примере мы создали том с именем mariadb. Будет создан каталог /var/lib/docker/volumes/mariadb/_data/ на хостовом сервере, куда будут размещаться наши файлы базы.
Выполним первый запуск нашего контейнера с mariadb:
В каталоге тома должны появиться файлы базы данных. В этом можно убедиться командой:
Теперь подключаемся к командной строке внутри контейнера с сервером базы данных:
Подключаемся к mariadb:
Меняем пароль для учетной записи root:
> SET PASSWORD FOR ‘root’@’localhost’ = PASSWORD(‘New_Password’);
Выходим из командной строки СУБД:
Выходим из контейнера:
Останавливаем сам контейнер — он нам больше не нужен с данными параметрами запуска:
docker stop maria_db
И запускаем его по новой, но уже без системной переменной с паролем и необходимостью его удаления после остановки:
Сервер баз данных готов к работе.
Подключение к базе из веб-сервера
По отдельности, наши серверы готовы к работе. Теперь настроим их таким образом, чтобы из веб-сервера можно было подключиться к СУБД.
Зайдем в контейнер с базой данных:
Подключимся к mariadb:
Создадим базу данных, если таковой еще нет:
> CREATE DATABASE docker_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
* в данном примере мы создаем базу docker_db.
Создаем пользователя для доступа к нашей базе данных:
> GRANT ALL PRIVILEGES ON docker_db.* TO ‘docker_db_user’@’%’ IDENTIFIED BY ‘docker_db_password’;
* и так, мы дали полные права на базу docker_db пользователю docker_db_user, который может подключаться от любого хоста (%). Пароль для данного пользователя — docker_db_password.
Отключаемся от СУБД:
Выходим из контейнера:
Теперь перезапустим наши контейнеры с новым параметром, который будет объединять наши контейнеры по внутренней сети.
Останавливаем работающие контейнеры и удаляем их:
docker stop maria_db web_server
docker rm maria_db web_server
docker network create net1
* мы создали сеть net1.
Создаем новые контейнеры из наших образов и добавляем опцию —net, которая указывает, какую сеть будет использовать контейнер:
* указав опцию —net, наши контейнеры начинают видеть друг друга по своим именам, которые мы задаем опцией —name.
Готово. Для проверки соединения с базой данных в php мы можем использовать такой скрипт:
* в данном примере мы подключаемся к базе docker_db на сервере maria_db с использованием учетной записи docker_db_user и паролем docker_db_password.
После его запуска, мы увидим либо пустой вывод (если подключение выполнено успешно), либо ошибку.
Использование docker-compose
В отличие от docker, с помощью docker-compose можно разворачивать проекты, состоящие из нескольких контейнеров, одной командой.
И так, автоматизируем запуск наших контейнеров с использованием docker-compose. Необходимо, чтобы он был установлен в системе.
Сначала удалим контейнеры, которые создали на предыдущих этапах:
Переходим в каталог для наших сборок:
Создаем yml-файл с инструкциями сборки контейнеров через docker-compose:
maria_db:
image: mariadb
container_name: maria_db
restart: always
volumes:
— /var/lib/docker/volumes/mariadb/_data/:/var/lib/mysql
* в формате yml очень важное значение имеют отступы. Если сделать лишний пробел, то мы получим ошибку.
* где:
Запускаем сборку наших контейнеров с помощью docker-compose:
Запускаем контейнеры в режиме демона:
Проверяем, какие контейнеры запущены:
Возможные проблемы
Рассмотрим некоторые проблемы, которые могут возникнуть в процессе настройки.
1. Errors during downloading metadata for repository ‘AppStream’
Ошибка возникает при попытке собрать имидж на Linux CentOS 8. Полный текст ошибки может быть такой:
Errors during downloading metadata for repository ‘AppStream’:
— Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=container [Could not resolve host: mirrorlist.centos.org]
Error: Failed to download metadata for repo ‘AppStream’: Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=container [Could not resolve host: mirrorlist.centos.org]
Причина: система внутри контейнера не может разрешить dns-имена в IP-адрес.
Решение: в CentOS 8 запросы DNS могут блокироваться брандмауэром, когда в качестве серверной части (backend) стоит nftables. Переключение на iptables решает проблему. Открываем файл:
Docker web server nginx php mysql
Docker running Nginx, PHP-FPM, Composer, MySQL and PHPMyAdmin.
Before installing project make sure the following prerequisites have been met.
We’ll download the code from its repository on GitHub.
We’ll generate and configure SSL certificate for nginx before running server.
We’ll configure Xdebug for IDE (PHPStorm or Netbeans).
By this point we’ll have all the project pieces in place.
When developing, you can use Makefile for doing recurrent operations.
When running, you can use docker commands for doing recurrent operations.
To run the docker commands without using sudo you must add the docker group to your-user:
All requisites should be available for your distribution. The most important are :
Check if docker-compose is already installed by entering the following command :
Check Docker Compose compatibility :
The following is optional but makes life more enjoyable :
On Ubuntu and Debian these are available in the meta-package build-essential. On other distributions, you may need to install the GNU C++ compiler separately.
You should be careful when installing third party web servers such as MySQL or Nginx.
This project use the following ports :
| Server | Port |
|---|---|
| MySQL | 8989 |
| PHPMyAdmin | 8080 |
| Nginx | 8000 |
| Nginx SSL | 3000 |
To install Git, download it and install following the instructions :
Go to the project directory :
Configure Nginx With SSL Certificates
If you modify the host name, do not forget to add it to the /etc/hosts file.
Generate SSL certificates
Do not modify the etc/nginx/default.conf file, it is overwritten by etc/nginx/default.template.conf
Edit nginx file etc/nginx/default.template.conf and uncomment the SSL server section :
If you use another IDE than PHPStorm or Netbeans, go to the remote debugging section of Xdebug documentation.
For a better integration of Docker to PHPStorm, use the documentation.
Get your own local IP address :
Edit php file etc/php/php.ini and comment or uncomment the configuration as needed.
Set the remote_host parameter with your IP :
Run the application
Copying the composer configuration file :
Start the application :
Please wait this might take a several minutes.
Open your favorite browser :
Stop and clear services
When developing, you can use Makefile for doing the following operations :
Разработка под Docker. Локальное окружение. Часть 1
Возможно, одна из самых основных причин почему мне нравится докер это то, что он позволяет избавиться от необходимости установки на компьютер различных сервисов. К их числу можно отнести и сам веб-сервер Apache или Nginx, базы данных и прочие компоненты инфраструктуры приложения. Вся инфраструктура прописана в конфигурационном файле docker-compose.yml и запускается одной командой вместе с вашим приложением. Все что нужно разработчику работающему с докером, это по сути сам докер и любимая среда разработки и ВСЕ!
Для полноты дальнейшего повествования все-таки придется бегло рассказать, что такое докер и его основные понятия.
Итак, докер следует рассматривать, как некоторую систему виртуализации и контейнеризации.
Одно из базовых понятий докера — это образ. Образ можно сравнить с файлом (может быть даже с исполняемым файлом программы), в котором содержится некоторая информация. Докер может выполнить запуск образа. Запущенный образ называется контейнером. Может быть запущено несколько контейнеров одного и того же образа.
Так что же содержится в образе?
Может быть образ операционной системы. К примеру, образ ubuntu. Может быть образ с базой данных, веб-сервером и php и практически с чем угодно. Для начала этих знаний нам будет достаточно.
Предполагается, что у читателя уже установлен сам docker и утилита docker-compose.
Начнем развертывание нашего окружения от простого к более сложному.
Урок №1. Установка Nginx
Попробуем для начала установить один лишь Nginx. Создадим docker-compose.yml следующего содержания:
Вводим в адресной строке браузера http://localhost/ и нашему взору должно открыться приветствие «Welcome to nginx!». Если все так, вы на верном пути.
Что тут вообще происходит?
Для понимания структуры compose-файла я рекомендую обратиться к официальной документации, несмотря на то, что она на английском это лучший источник информации. В документации описаны все возможные опции, которые могут быть использованы.
Разберем представленный файл:
Главным хранилищем всех образов является Docker Hub там представлено множество различных готовых образов (Можно собирать и свои собственные, но об этом позже). Объявленный образ nginx является одним из них.
Что касается «проброса» портов. Если вы указываете соответствие 80:80, как и в указанном примере, то nginx будет доступен по адресу localhost:80 или просто localhost. Если же 80 порт уже занят, то можно указать 8080:80. Тогда сайт будет доступен по адресу localhost:8080. И соответственно, если вы вовсе забыли указать данную директиву ports, то порт будет доступен только внутри контейнера и nginx через браузер уже будет недоступен.
Контейнер запущен. А как собственно с ним работать?
Установка Веб-сервера предполагает, что мы хотим с его помощью получать и просматривать html-страницы сайта. Появляется вопрос. Каким образом можно передать в контейнер какие-либо html-файлы? В этом нам помогут volumes
volumes
Приведем наш docker-compose.yml к следующему виду:
При монтирование папка по указанному адресу внутри контейнера заменяется папкой с локального компьютера.
Чтобы все заработало, создадим папку html на одном уровне с файлом docker-compose.yml и добавим в нее файл index.html с произвольным текстом. Например, Hello from Docker!
Проверяем в браузере получившийся результат. И видим: Hello from Docker! Все получилось.
Очередная статья про Docker для новичка [nginx + php-fpm + postgresql + mongodb]
Всем доброго времени суток. Вдохновленный целым набором статей на тему поднятия окружения на докере, я решил поделиться своим опытом по данному вопросу.
Сразу оговорюсь, эта статья так сказать «от новичка новичку», поэтому постараюсь подробно рассказать обо всех сложностях и вопросах, которые у меня возникли в процессе настройки окружения в Docker.
Добро пожаловать под кат!
Итак, все что я опишу ниже, я буду делать на ноутбуке известной «фруктовой компании», но так как ранее я делал тоже самое на VDS под управлением Centos 7, то я буду делать небольшие лирические отступления с описание, как я это делал на VDS.
Начнем мы естественно в регистрации на docker hub, который будет выступать в качестве системы контроля версий, но только для наших контейнеров. Docker hub при бесплатном использовании позволяет иметь только 1 приватный репозиторий, поэтому мы будем каждый отдельный образ помечать соответствующими тегами — nginx, php7-fpm. Я не буду описывать создание репозитория, думаю, ни у кого с этим проблем не возникнет.
Теперь мы можем установить сам docker на нашу рабочую станцию — в моем случае это описание находится здесь.
При установке Docker на Mac у нас сразу устанавливается docker toolbox, в котором есть необходимый нам инструмент docker-compose. Мы будем использовать его для объединения наших контейнеров о общее окружение.
Далее логинимся в нашем Докере:
Теперь нам доступны наши приватные репозитории (правда там пока пусто), там правда сейчас пусто, но мы это скоро исправим:)
Для своего проекта я сделал следующую структуру файлов:
Для проекта я буду использовать кастомные образы для nginx и fpm, поэтому их я вынес в отдельные директории. Кастомные образы описываются при помощи Dockerfile. Вот мои:
Скрипт из официального образа PHP от Docker Hub позволяет легко установить нужные расширения:
Вся подготовительная работа проведена проведена, теперь надо описать как наши контейнеры будут взаимодействовать. Как я уже писал, делать это мы будем через docker-compose и правила взаимодействия нужно описать в файле docker-compose.yml. Вот мой:
Теперь можно запустить наши контейнеры:
Все, наши контейнеры работают и линкуются, но кое-что я сделал не так, а именно — мы для запуска контейнера всегда ссылаемся на Dockerfile, это не очень удобно. Сделаем так:
Теперь наши контейнеры управляются через docker hub и Dockerfile’ы нам больше не нужны.
Исправим docker-compose.yml:
А вот теперь я понял, что забыл добавить расширение pcntl для php. Но это легко поправить.
Для начала подключимся к нужному контейнеру:
И добавить необходимое расширение:
Отлично, в контейнер добавили, но мы же хотели использовать docker hub в качестве VCS — значит надо закомитить изменения:
Добавим еще контейнеры баз данных (postgresql и mongodb):
И теперь выполняем:
Докер добавит нам новые контейнеры к уже запущенным. Но я открыли порты для внешнего доступа, но мы указали пароль только для PostgreSql, нужно тоже самое сделать и для mongodb — как это сделать (и не только) подробно описано здесь.
Базы данных из php теперь доступны по хостам postgres и mongo соответственно, т.е. для подключения, например, к mongodb мы должны написать следующее:
На этом все, спасибо за внимание. Прошу учесть, что все описанное является исключительно моим собственным опытом и не претендует на звание идеального подхода к настройке окружения через docker.

