docker-compose пример стека apache2, php, mysql, phpmyadmin, и проксирование nginx
Создадим с помощью Docker Compose ещё один пример, довольно часто используемый стек: сервер apache2 с php, базой данных на mysql, и контейнер для управления базой с помощью phpmyadmin, а также настроим прокси на nginx ещё в одном отдельном контейнере, чтобы было удобно всем этим пользоваться. Таким образом мы увидим всю логику происходящего, для создания подобных конфигураций, для собственных нужд.
Если у вас ещё не установлены docker и docker-compose,
то в Debian подобных дистрибутивах это делается так:
Теперь приступим.
Рассмотрим всё на простом примере. Создаём каталог product с будущим проектом
mkdir product cd product
это будет корень проекта.
создаём каталоги
mkdir php mkdir html mkdir html/apache_logs mkdir mysql
создаём файлы
touch php/Dockerfile touch html/index.php touch docker-compose.yaml touch mysite.conf touch nginx.conf
Заходим внутрь каталога php (в нём мы создадим файл именно с таким именем Dockerfile, даже регистр имеет значение, это файлы для создания docker образов, на тот случай если нам нужно что-то добавить в базовый образ который мы берём из dockerhub, в этом примере мы доработаем образ для нашего php сервера)
Затем идём в каталог html
Фактически этот каталог и будет, для файлов нашего сайта, который мы планируем запустить на этом сервере, поэтому в нём сразу создаём файл index.php для тестирования работоспособности наших контейнеров.
Так же в этом же каталоге создаём подкаталог apache_logs
для логов сервера.
Выходим обратно на уровень product и создаём ещё один каталог для второго контейнера баз данных, фактически для хранения на хосте файлов с базой данных и настроек,
mysql
Теперь основное действие, здесь же на корневом уровне проекта, создаём файл для сборки контейнеров
называется вот так: docker-compose.yaml
в точности копируем, вместе с расширением yaml
Теперь создадим файл настроек apache2 который будет работать в контейнере, mysite.conf это файл конфигурации нашего сайта для сервера apache2 который мы смонтируем внутрь контейнера при его создании. В тот же контейнр мы смонтируем и каталог html
Также создаём файл nginx.conf, этот файл будет отвечать за настройку для третьего контейнера, с нашим прокси.
А во второй контейнер, с базой данных мы смонтируем каталог mysql
Как всё это будет монтироваться, мы наглядно мы увидем в содержимом файла docker-compose.yaml
А пока, сейчас у вас должна быть вот такая структура корня проекта, каталог product:
☯
Terminal:
⌕
≡
✕
.
├── nginx.conf
├── docker-compose.yaml
├── html
│ ├── apache_logs
│ └── index.php
├── mysite.conf
├── mysql
└── php
└── Dockerfile
создайте все эти файлы и каталоги, и приступим к их заполнению.
начнём с файла
docker-compose.yaml Обратите внимание все отступы, в этом файле, как и оступы в файлах Dockerfile, строго одного уровня, они имееют синтаксическое значение, почти точно такое же как и в файлах python, поэтому внимательно соблюдайте такие оступы, если желаете, чтобы у вас всё работало без ошибок.
обратите внимение, все строки которые начинаются с # можно просто удалить, они являются комментариями и никак не учитываются при сборке.
☯
Terminal:
⌕
≡
✕
version: '3'
services:
#первый контейнер для php и сервера apache2
php:
build:
context: ./php
dockerfile: Dockerfile
ports:
#здесь мы указываем на каких портах будет работать контейнер. т.е. первым идёт порт хоста с которого мы запустим контейнер
#вторым через : идёт порт внутри контейнера
- '81:80'
# - '25:25'
volumes:
# это деректива монтирования
# здесь показаны вначале локальные каталоги на вашем хосте, из корня проекта, а затем через знак : каталоги где они будут расположены и как называться внутри контейнеров
- ./html:/var/www/html
- ./html:/usr/local/apache2/htdocs
- ./html/apache_logs:/var/log/apache2
- ./mysite.conf:/usr/local/apache2/conf/extra/mysite.conf
depends_on:
# здесь мы указываем зависимость или связь со вторым образом, который мы назовём db и пропишем ниже
- db
environment:
# здесь мы указываем переменную окружения, в данном случае зададим переменной DOMEN, url адрес, обратите внимаение как
# эта переменная используется при создании контейнера, на локально хосте если нет домен можно использовать localhost или обращаться к серверу просто по его ip
- DOMAIN=ramanzes.freemyip.com
networks:
# и ещё один важный параметр это внутренняя сеть, наших контейнеров по которой все они будут работать друг с другом
- myapp_network
#второй контейнер для сервера mysql создаём просто из образа
db:
image: mysql:latest
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=base_docker
- MYSQL_USER=docker
- MYSQL_PASSWORD=dockerpassword
- MYSQL_ROOT_PASSWORD=rootpassword
networks:
- myapp_network
#третий контейнер для сервиса phpmyadmin, для управления базой данных, также создаём просто из образа
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- '8081:80'
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
depends_on:
- db
networks:
- myapp_network
#четвёртый контейнер для сервера nginx создаём просто из образа, у нас будет работать, как прокси, это будет прописано в файле nginx.conf
proxy:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- '80:80'
networks:
- myapp_network
#без оступа как и services начинаеся деректива сети.Для простоты я добавлю указание использования сети по умолчанию, называемой bridge.
networks:
myapp_network:
driver: bridge
Теперь файл mysite.conf:
В котором, кстати отступы, уже не имеют синтаксического значения, только для наглядности.
Эта конфигурация будет добавлена внутрь контейнера, в момент его сборки...
☯
Terminal:
⌕
≡
✕
ServerRoot "/usr/local/apache2" #обратите внимание здесь указывается внутренний порт контейнера 80, а не внешний, что у нас тут был бы как 81ServerName ramanzes.freemyip.com DocumentRoot "/var/www/html" Options Indexes FollowSymLinks AllowOverride All Require all granted SetHandler application/x-httpd-php ErrorLog "/var/log/apache2/my_error.log" CustomLog "/var/log/apache2/my_access.log" combined
Теперь файл nginx.conf:
В котором, кстати отступы, уже не имеют синтаксического значения, только для наглядности.
Эта конфигурация будет добавлена внутрь контейнера nginx, в момент его сборки...
☯
Terminal:
⌕
≡
✕
server {
# здесь также указывается внутренний порт контейнера(если бы они отличались например 83:80), т.е. второй 80 это внутренний
#а не внешний из наших настроек но у нас эти порты идентичны docker-compose(80:80)
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
#локация это slug, доп адрес в url после proxy_pass здесь пусто
location / {
#а здесь уже указываются внешние порты из нашего docker-compose(81:80 для php) внешний это 81
proxy_pass http://ramanzes.freemyip.com:81/;
}
#локация это slug, доп адрес в url после proxy_pass, а здесь + /phpmyadmin
location /phpmyadmin {
#а здесь уже указываются внешние порты из нашего docker-compose(8081:80 для phpmyadmin) внешний здесь 8081
proxy_pass http://ramanzes.freemyip.com:8081/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
теперь файл ├── php
│ └── Dockerfile
Dockerfile
☯
Terminal:
⌕
≡
✕
FROM php:8.0-apache
RUN apt-get update \
&& apt-get install -y libpq-dev libonig-dev \
&& docker-php-ext-install pdo pdo_mysql mysqli
RUN apt-get install -y apache2-bin
RUN a2enmod alias
RUN a2enmod rewrite
RUN service apache2 restart
теперь файл
├── html
│ └── index.php
Для проверки связи контейнеров, вот пример на PHP, который создает таблицу в базе данных PostgreSQL, заполняет ее случайным текстом и выводит этот текст на экран в браузере:
☯
Terminal:
⌕
≡
✕
<h1>Да php работает в It works</h1>
<?php phpinfo(); ?>
<?php
// Подключение к базе данных
$servername = "db";
$username = "docker";
$password1 = "dockerpassword";
$password2 = "rootpassword";
$dbname = "base_docker";
$conn = new mysqli($servername, $username, $password1, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Создание таблицы
$sql = "CREATE TABLE IF NOT EXISTS random_text (
id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
text VARCHAR(255) NOT NULL
)";
if ($conn->query($sql) === TRUE) {
echo "Table 'random_text' created successfully<br><br>";
} else {
echo "Error creating table: " . $conn->error;
}
// Заполнение таблицы случайным текстом
for ($i = 1; $i <= 10; $i++) {
$randomText = generateRandomText();
$sql = "INSERT INTO random_text (text) VALUES ('$randomText')";
if ($conn->query($sql) === TRUE) {
echo "Inserted random text: $randomText<br>";
} else {
echo "Error inserting text: " . $conn->error;
}
}
// Вывод текста из базы данных на экран
$sql = "SELECT * FROM random_text";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<br>Random Text:<br>";
while($row = $result->fetch_assoc()) {
echo $row["text"] . "<br>";
}
} else {
echo "No random text found";
}
$conn->close();
// Функция для генерации случайного текста
function generateRandomText($length = 20) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$randomText = '';
for ($i = 0; $i < $length; $i++) {
$randomText .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomText;
}
?>
Перед использованием этого примера необходимо заменить значения "имя_пользователя", "пароль" и "имя_базы_данных" на соответствующие данные вашей базы данных MySQL, которые вы указали при сборке контейнера в файле docker-compose.yaml. Убедитесь, что у вас есть соединение с базой данных для выполнения примера. Также учтите, что данное решение для базы данных MySQL, и вам понадобится установленный драйвер PHP для работы с MySQL, что мы уже сделали с помощью php/Dockerfile.
Приведенный пример создает таблицу 'random_text' с двумя столбцами: 'id' (идентификатор) и 'text' (текстовое поле). Затем он заполняет таблицу случайным текстом, используя функцию generateRandomText(). Наконец, он извлекает текст из базы данных и выводит его на экран в браузере.
После приведения своего рабочего каталога в такой вид, находясь в корне проекта, т.е. в том же каталоге, же где и файл docker-compose.yaml
Выполняем следующие команды по порядку. Загрузим образы на свой компьютер.
Создадим контейнеры из этих образов и запустим их, следующей командой:
Убедимся, что контейнеры запустились успешно:
Ну и понятное дело, что если вы откроете в браузере домен в моём случае это http://ramanzes.freemyip.com/, ну или localhost, который вы указали в образе php при создании web сервера, вы увидете свой сервер в работе.
http://ramanzes.freemyip.com/phpmyadmin/ или localhost/phpmyadmin/, http://your-domen/phpmyadmin/ если вы тестируете на домашнем компьютере, или ip адрес сервера xxx.xxx.xxx.xxx/phpmyadmin/ обратите внимание, что слэш на конце адреса имеет значение, и его нужно указывать, чтобы всё работало.
для того чтобы войти в phpmyadmin нужно вводить следующие данные исходя из наших настроек
-
Создано 23.06.2023 17:00:00
-
Roman Sakhno

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.