Начало работы с Docker. Часть пятая
Взаимодействие служб apache и mysql
Теперь запускаем наши службы
И смотрим ini-файлы внутри контейнера
Вроде все в порядке, так что можем поработать из php-скрипта с базой данныx:

Три службы: Apache+PHP, MySQL и phpMyAdmin
Давайте отредактируем файл
/www/docker-compose.yml и добавим еще один контейнер:
Открываем браузер и набираем в адресной строке http://localhost:8080 :

Взаимодействие контейнеров по сети
Сеть Docker построена на Container Network Model (CNM), которая позволяет любому желающему создать свой собственный сетевой драйвер. Таким образом, у контейнеров есть доступ к разным типам сетей и они могут подключаться к нескольким сетям одновременно. Помимо различных сторонних сетевых драйверов, у самого Docker-а есть 4 встроенных:
Сети типа мост (bridge)
Чтобы проинспектировать ее свойства, запустим команду
Также можно создать свои собственные bridge-сети при помощи команды
Bridge-интерфейсы хоста
Можно получить больше данных о статусе моста при помощи утилиты brctl (должен быть установлен пакет bridge-utils ):
Как только мы запустим контейнеры и привяжем их к этой сети, интерфейс каждого из этих контейнеров будет выведен в списке в отдельной колонке. А если включить захват трафика в bridge-интерфейсе, то можно увидеть, как передаются данные между контейнерами в одной подсети.
Виртуальные интерфейсы Linux
Container Networking Model дает каждому контейнеру свое собственное сетевое пространство. Если запустить команду ip addr внутри контейнера, то можно увидеть его интерфейсы такими, какими их видит сам контейнер:
Откроем еще один терминал на хосте и запустим контейнер:
Теперь опять выполним на хосте команды
Разработка под Docker. Локальное окружение. Часть 2 — Nginx+PHP+MySql+phpMyAdmin
Для лучшего понимания нижеследующего материала сначала рекомендуется ознакомится с Предыдушим постом
Рассмотрим пример развертки локального окружения состоящего из связки Nginx+PHP+MySql+phpMyAdmin. Данная связка очень популярна и может удовлетворить ряд стандартных потребностей рядового разработчика.
Как и в прошлом посте акцент будет смещен в сторону утилиты docker-compose, чем докера в чистом виде.
Итак, поехали!
Начнем вот с такого docker-compose.yml, который лежит в отдельной папке proxy:
В представленном файле описана конфигурация для создания одного контейнера с именем proxy на базе образа image: jwilder/nginx-proxy и создание сети с одноименным именем. Директива networks указывает к каким сетям подключен контейнер, в данном примере, это наша сеть proxy.
При создание сети директиву driver: bridge можно было бы и не указывать. Драйвер типа «мост» является драйвером по умолчанию. Данный контейнер будет связываться по сети с прочими контейнерами.
Образ jwilder/nginx-proxy является базовым и взят и Docker Hub там же представлено довольно обширное и подробное описание по его использованию. Принцип работы nginx-proxy довольно простой, он через пробрасываемый сокет докера получает доступ к информации о запущенных контейнерах, анализирует наличие переменной окружения с именем VIRTUAL_HOST и перенаправляет запросы с указанного хоста на контейнер, у которого данная переменная окружения задана.
Данный вывод информирует нас о том, что в начале была создана сеть proxy_proxy, а затем был создан контейнер proxy_proxy_1. Имя сети получилось из названия папки, в которой размещался файл docker-compose.yml, у меня это proxy и одноименного имени сети.
Если ввести команду docker network ls, то мы увидим список сетей докера в нашей системе и одна из них должна быть proxy_proxy.
Имя контейнера строиться по аналогичному принципу имя папки плюс название сервиса и число, которое позволяет, чтобы контейнеры со схожими именами не дублировались. Через директиву container_name можно задать имя контейнера явно, но я считаю это довольно бесполезной функцией. Подробнее пойдет речь об этом в следующих постах.
Создаем второй docker-compose.yml следующего содержания:
Что тут у нас объявлено?
Перечислены четыре сервиса: nginx, php, mysql и phpmyadmin. И две сети. Одна сеть прокси с именем frontend, объявлена как внешняя сеть и новая внутренняя сеть backend. Драйвер для нее не указан, как и писал ранее, будет использоваться драйвер по умолчанию типа bridge.
nginx
Тут примерно должно быть все понятно. Используем базовый образ с докер хаб. Переменная окружения необходима для работы прокси и сообщает ему, по какому адресу должен быть доступен контейнер. Опция depends_on указывает, на зависимость данного контейнера от контейнера php. Это означает, что вперед будет запущен контейнер php, а после него будет выполнен запуск зависимого от него контейнера nginx. Далее пробрасываем конфигурацию для нашего nginx. Она будет чуть ниже и монтируем папку с html. Так же замечаем, что контейнер имеет доступ сразу к двум сетям. Он должен связываться и прокси из сети frontend и с php из сети backend. В принципе, можно было бы все контейнеры и в одну сеть frontend попихать, но я придерживаюсь, что подобное разделение более верное.
default.nginx — это конфиг для nginx, который пробрасывается в контейнер. Ключевой момент тут директива fastcgi_pass php:9000. Она задает адрес FastCGI-сервера. Адрес может быть указан в виде доменного имени или IP-адреса, и порта.
php:9000 — имя сервиса это и есть адрес FastCGI-сервера. Nginx обращаясь по адресу php будет получать IP-адрес контейнера, в котором работает php. Порт 9000 это стандартный порт, он объявлен при создание базового контейнера. Данный порт доступен для nginx по сети, но не доступен на хостовой машине, так как не был проброшен.
Тут необычно то, что не указан образ. Вместо этого происходит сборка собственного образа прямо из compose-файла. Директива context указывает на папку, в которой находится Dockerfile.
В Dockerfile указано, что для сборки используется базовый образ php:7.3.2-fpm, далее выполняется запуск команд для установки php-расширений. Далее копируется composer из другого базового образа и устанавливается рабочая директория для проекта. Детальнее вопросы сборки рассмотрю в других постах.
Также во внутрь контейнера пробрасывается файл php.ini и папка html с нашим проектом.
Заметим, что php находится в сети backend и к примеру прокси к нему доступ получить уже не может.
mysql
База находится в сети backend, что позволяет ей держать связь с php. В базовом образе используется стандартный порт 3306. Он доступен по сети докера для php, но не доступен на хостовой машине. Если выполнить проброс для данного порта, то можно к нему коннектиться к примеру из того же PHPSTORM. Но если вам достаточно интерфейса phpmyadmin, то этого можно и не делать.
phpmyadmin
Официальный образ phpmyadmin. В переменных окружения используется VIRTUAL_HOST для взаимодействия с прокси, аналогично nginx. PMA_USER и PMA_PASSWORD доступ к базе. И PMA_HOST сам хост базы. Но это не localhost, как обычно бывает, а mysql. Т.е. связь с базой доступна по имени ее сервиса, т.е. mysql. Контейнер phpmyadmin может связаться с базой, т.к имеет подключение к сети backend.
Видим следующий вывод:
Видим, что в начале происходит создание сети lesson2_backend, затем сборка образа php, потом может происходить скачивание образов, которых еще нет в системе (pull) и собственно запуск описанных сервисов.
Последний штрих, чтобы все заработало это добавление в hosts или доменов site.local и phpmyadmin.local.
Содержимое index.php может быть следующим:
Тут мы проверяем корректность подключения расширения php — mysqli, которое было добавлено при сборке Dockerfile.
И заметим, что для связи с контейнером используется название сервиса — mysql.
Структура всего проекта получилась следующей:
🐳 Docker-compose для MySQL с phpMyAdmin
Docker-compose – полезная утилита для управления многоконтейнерными приложениями.
В нашем предыдущем руководстве я обсуждал сохранение постоянных данных Docker-контейнеров MySQL с использованием томов Docker.
После того, как вы запустили контейнер MySQL, вы можете подключиться через терминал напрямую.
Но любителям phpMyAdmin может понадобиться веб-интерфейс для управления базами данных.
В этом руководстве вы научитесь запускать контейнеры MySQL Docker вместе с Docker контейнером phpMyAdmin с помощью команды docker-compose.
Предпосылки
В этом руководстве предполагается, что вы уже сделали следующее:
Если что, у нас есть руководства:
Как развернуть Docker контейнер MySQL с phpMyAdmin
phpMyAdmin – самое популярное веб-приложение для управления серверами баз данных MySQL.
В этом примере мы просто используем пример контейнера Docker для MySQL и phpMyAdmin.
Поэтому сначала создайте файл docker-compose.yml в вашей системе со следующим содержимым.
docker-compose.yml:
Сохраните файл и закройте его.
Затем выполните следующую команду, чтобы создать контейнеры Docker с помощью файла конфигурации docker-compose.yml.
Приведенная выше команда запустит два контейнера Docker, один для сервера базы данных MySQL и один для phpMyAdmin.
Также будет создан том данных, который прикреплен к контейнеру MySQL, чтобы сделать данные постоянными.
Теперь зайдите в phpMyAdmin с помощью веб-браузера.
Я запускаю этот пример на моей локальной машине.
Таким образом, используется host как localhost с портом 8081, определенным в конфигурации docker compose.
В ам нужно изменить localhost с IP-адресом вашего сервера для удаленного доступа к нему.
jcavat / Dockerfile
| Create this directories structure: |
| . |
| ├── docker-compose.yml |
| ├── Dockerfile |
| ├── dump |
| │ └── myDb.sql |
| ├── sessions |
| └── www |
| └── index.php |
| html > |
| head > |
| title > Hello. title > |
| meta charset =» utf-8 » > |
| link rel =» stylesheet » href =» http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css » > |
| script src =» https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js » > script > |
| script src =» http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js » > script > |
| head > |
| body > |
| div class =» container » > |
| echo « |
Hi! I’m happy
This comment has been minimized.
Copy link Quote reply
Azkom commented Feb 26, 2018 •
In Dockerfile is it not 7.2.2-apache instead of 7.1.2-apache?
This comment has been minimized.
Copy link Quote reply
redigaffi commented Mar 21, 2018
In the SQL file you have to specify which database you want to use at the top:
CREATE DATABASE IF NOT EXISTS app; USE app;
If not it won’t work (at least for me).
This comment has been minimized.
Copy link Quote reply
MichaelPolla commented Mar 24, 2018
@redigaffi just tried it yet, it works out-of-the-box.
Here’s what I did, in case you forgot something :
This comment has been minimized.
Copy link Quote reply
publicJorn commented Mar 26, 2018 •
@jcavat could you elaborate on what this does, at the bottom of docker-compose.yml?
I suppose it has something todo with the persistent:/var/lib/mysql entry in db, but I’m not sure what I can/should do with it.
Also, what does the /sessions directory do?
This comment has been minimized.
Copy link Quote reply
MichaelPolla commented Apr 2, 2018 •
The line persistent:/var/lib/mysql mounts the persistent volume as /var/lib/mysql inside the db container. /var/lib/mysql is where MySQL by default will write its data files.
You can learn about this in the MySQL image description under the «Where to Store Data» section (bottom of the page).
Concerning the /sessions folder, I don’t know why it’s needed; it works without it. I’ll ask @jcavat next time I see him 🙂
This comment has been minimized.
Copy link Quote reply
sudamar commented May 28, 2018 •
Error at the connect with phpmyadmin: mysqli_real_connect(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name does not resolve
Error at the connect with http://localhost:8001/ : (403) You don’t have permission to access / on this server.
This comment has been minimized.
Copy link Quote reply
OmegaWolfProjects commented Jun 1, 2018 •
sudamar: I had the exact same problem as you. I solved it by using an older version of the software i.e. by doing the following:
Clean everything:
Dockerfile
I changed the Dockerfile to the following (using an older version):
docker-compose.yml file
. and I changed the part of the docker-compose.yml file from:
Rebuild:
Now wait about 20 seconds before trying to access the below webpages (I noticed that it takes some time for the mysql service to start up etc).
Now it you browse to http://192.168.1.106:8001/ and http://192.168.1.106:8000/index.php they both work (well they do for me now!)
This comment has been minimized.
Copy link Quote reply
jotjot commented Jun 25, 2018
Although I really believe that the decision of the MySQL maintainers is wrong, I do believe that they are not going to change it back. So, I verified out how it can work without downgrading. It is a bit more of work, but needs to be done only once:
Change/Create all users you need with the option «mysql_native_password»
This works fine for me, as the mysql data is persistent, and you can use the latest versions of the packages.
This comment has been minimized.
Copy link Quote reply
dileep021 commented Aug 5, 2018
not able to login in to phpmyadmin
mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
This comment has been minimized.
Copy link Quote reply
danangt49 commented Dec 28, 2018
not able to login in to phpmyadmin
mysqli_real_connect(): (HY000/2002): Operation timed out
This comment has been minimized.
Copy link Quote reply
AleSpreafico commented Jan 15, 2019
newest version of mysql doesn’t work.
downgrade to a mysql:5.7 or mariadb
This comment has been minimized.
Copy link Quote reply
charan432 commented Jan 29, 2019
@OmegaWolfProjects: Thank you for your comment. It solved half of my issues. I have followed all the steps given in the comment. Still, I can’t access http://192.168.1.106:8001/. It is showing Forbidden access.
Then, I have run below command in my command shell
Here, When I tried to see list of files by using ls command. It is not showing any of the files like index.php (The directory is empty).
Please help me to fix this issue
This comment has been minimized.
Copy link Quote reply
Bargefull commented Feb 24, 2019 •
This comment has been minimized.
Copy link Quote reply
vigneshindn commented Mar 23, 2019
I got a error php-mysql module missing any solution please
This comment has been minimized.
Copy link Quote reply
KirinFuji commented Apr 13, 2019
This is not working out of the box on the latest centos7 latest docker latest docker-compose:
ERROR: In file ‘./docker-compose.yml’, volume must be a mapping, not a NoneType.
This comment has been minimized.
Copy link Quote reply
KirinFuji commented Apr 13, 2019 •
All I had to do was move:
From the bottom of the docker-compose.yml file
To the Top (above services: below version:) of the file as shown:
This got the container to build and run. But I am having issues apparently due to a default character set changing. I may work on this later really wanting to use this.
Warning: mysqli_connect(): Server sent charset (255) unknown to the client.
Warning: mysqli_connect(): (HY000/2054): Server sent charset unknown to the client.
This comment has been minimized.
Copy link Quote reply
Jhessyjhordon commented Apr 30, 2019
I changed the Dockerfile to the following (using the new version):
FROM php:7.3-apache RUN docker-php-ext-install mysqli
. and I changed the part of the docker-compose.yml file from:
db: image: mysql
To
db: image: mysql:8.0
All this is in a virtual server (at host [1 & 1] (https://www.ionos.com/servers/vps)), a Linux server on Ubuntu that contains my Docker.
On this Docker I try to install a web server on which I will put websites and databases.
I chose to do this because I will need access to databases from a JAVA application. Something that would not be possible if I had chosen a simple web host instead of this virtual server.
Устанавливаем phpMyAdmin с помощью Docker
Это продолжение статьи «Локальная среда для PHP разработки с помощью Docker«, в ней мы создали среду со следующими компонентами:
Многие используют phpMyAdmin для просмотра и администрирования базы данных MySQL, поэтому в качестве своеобразного домашнего задания нужно было самостоятельно добавить еще один контейнер с phpMyAdmin, ниже я покажу как это сделать.
Устанавливаем
Ставить будем из официального образа https://hub.docker.com/r/phpmyadmin/phpmyadmin/, все что нам нужно сделать это добавить в docker-compose.yml вот такой код:
Теперь останавливаем нашу сборку если она запущена
И запускаем заново с флагом —build чтобы все пересобрать, поскольку мы изменили файл docker-compose.yml
Вроде все запустилось )

Попробуем перейти по http://localhost:8081/ и видим по этому адресу phpMyAdmin, чтобы в него войти используем логин root, а пароль secret (мы его задали в docker-compose.yml в настройках контейнера mysql).

Протестируем
Для теста попробуем установить WordPress. Для начала зайдем в phpMyAdmin и создадим базу данных blog.
Далее в папке sites создадим каталог blog и закинем туда установочные файлы WordPress, теперь необходимо настроить NGINX.
В каталог /config/nginx добавляем файл blog.conf с настройками сайта:
Конфигурационный файл NGINX для WordPress
После этого нам нужно не забыть в файл HOSTS нашей ОС добавить:

