Bootstrap

Разберёмся с помощью примера, что такое docker-compose

Разберёмся с помощью примера, что такое docker-compose

Docker Compose - это инструмент в экосистеме Docker, который позволяет определить и управлять многоконтейнерными приложениями. Он предоставляет удобный способ описать конфигурацию приложения в YAML-файле, который содержит информацию о контейнерах, сетях, объемах и других настройках.

С помощью Docker Compose вы можете объединить несколько сервисов и контейнеров в единую систему, описывая их зависимости и конфигурацию. Это особенно полезно, когда ваше приложение состоит из нескольких сервисов, например, веб-сервера, базы данных и кэша, и вы хотите запустить их одним командой или управлять ими с помощью нескольких команд.

Docker Compose легко устанавливается и работает на разных платформах. Он позволяет создавать, запускать и останавливать множество контейнеров из вашего приложения всего лишь одной командой. Это упрощает развертывание и масштабирование приложений, особенно в средах разработки, тестирования и производства.

В этой статье рассмотрим как легко и просто можно поднимать свои web сервера, на примере стека технологий: apache2, c php и postgresql с помощью одной команды, если у вас установлен docker и docker-compose.

 

Если не установлены, то в Debian подобных дистрибутивах это делается так:


sudo apt update

sudo apt install docker

sudo apt install docker-compose

Теперь приступим.

Рассмотрим всё на простом примере. Создаём каталог  product с будущим проектом

mkdir product
cd product

это будет корень проекта.

создаём каталоги

mkdir php
mkdir html
mkdir html/apache_logs
mkdir pgsql

создаём файлы

touch php/Dockerfile
touch html/index.php
touch docker-compose.yaml
touch mysite.conf

Заходим внутрь каталога php (в нём мы создадим файл именно с таким именем Dockerfile, даже регистр имеет значение, это файлы для создания docker образов, на тот случай если нам нужно что-то добавить в базовый образ который мы берём из dockerhub, в этом примере мы доработаем образ для нашего php сервера)

Затем идём в каталог html

Фактически этот каталог и будет, для файлов нашего сайта, который мы планируем запустить на этом сервере, поэтому в нём сразу создаём файл index.php для тестирования работоспособности наших контейнеров.

 

Так же в этом же каталоге создаём подкаталог apache_logs

для логов сервера.

Выходим обратно на уровень product и создаём ещё один каталог для второго контейнера баз данных, фактически для хранения на хосте файлов с базой данных и настроек,

pgsql

Теперь основное действие, здесь же на корневом уровне проекта, создаём файл для сборки контейнеров

называется вот так: docker-compose.yaml
в точности копируем, вместе с расширением yaml

Теперь создадим файл настроек apache2 который будет работать в контейнере, mysite.conf это файл конфигурации нашего сайта для сервера apache2 который мы смонтируем внутрь контейнера при его создании. В тот же контейнр мы смонтируем и каталог html

А во второй контейнер, с базой данных мы смонтируем каталог pgsql

Как всё это будет монтироваться, мы наглядно мы увидем в содержимом файла docker-compose.yaml

А пока, сейчас у вас должна быть вот такая структура корня проекта, каталог product:

.
├── docker-compose.yaml
├── html
│   ├── apache_logs
│   ├── index.html
│   └── index.php
├── mysite.conf
├── pgsql
├── php
│   └── Dockerfile
└── README.md

создайте все эти файлы и каталоги, и приступим к их заполнению.

начнём с файла

docker-compose.yaml Обратите внимание все отступы, в этом файле, как и оступы в файлах Dockerfile, строго одного уровня, они имееют синтаксическое значение, почти точно такое же как и в файлах python, поэтому внимательно соблюдайте такие оступы, если желаете, чтобы у вас всё работало без ошибок.

обратите внимение, все строки которые начинаются с # можно просто удалить, они являются комментариями и никак не учитываются при сборке.

Terminal:

#любой комментарий в таком файле начинается со знака решётки
version: '3' 
services: 
 #первый контейнер для php и сервера apache2
 php: 
   build: 
     #обратите внимание как мы сначала указываем, где находится наш Dockerfile для сборки этого образа относительно корня проекта      
     context: ./php 
     dockerfile: Dockerfile 
     #если бы нам не нужно было добавлять никаких пакетов в образ то можно было вместо этих трёх строк выше начиная с build, для Dockerfile просто указать название образа, строка ниже. 
   #image: php:8.0-apache 
     #Но так мы ещё сделаем с образом для контейнеров базы данных ниже.
   ports: 
     #здесь мы указываем на каких портах будет работать контейнер. т.е. первым идёт порт хоста с которого мы запустим контейнер
     #вторым через : идёт порт внутри контейнера 
     - '80: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 
 #второй контейнер для сервера PostgreSQL создаём просто из образа
 db: 
   image: postgres:latest 
   volumes: 
     - ./pgsql:/var/lib/postgresql/data 
   environment: 
     - POSTGRES_USER=docker 
     - POSTGRES_PASSWORD=dockerpassword 
     - POSTGRES_DB=base_docker 
   networks: 
     - myapp_network 

#без оступа как и services начинаеся деректива сети.Для простоты я добавлю указание использования сети по умолчанию, называемой bridge. 
networks: 
 myapp_network: 
   driver: bridge

Теперь файл mysite.conf:

В котором, кстати отступы, уже не имеют синтаксического значения, только для наглядности.

Эта конфигурация будет добавлена внутрь контейнера, после сборки...

Terminal:


ServerRoot "/usr/local/apache2" 
Listen 80 

DocumentRoot "/var/www/html" 

 
   Options Indexes FollowSymLinks 
   AllowOverride All 
   Require all granted 
 

 
   SetHandler application/x-httpd-php 
 

ErrorLog "/var/log/apache2/error.log" 
LogLevel warn 
CustomLog "/var/log/apache2/access.log" combined


теперь файл ├── php
              │   └── Dockerfile

Dockerfile

Terminal:

FROM php:8.0-apache 

ENV PGSQL_DIR /var/lib/postgresql/data 

RUN apt-get update \ 
   && apt-get install -y libpq-dev postgresql-client \ 
   && docker-php-ext-install pdo pdo_pgsql 

 

теперь файл

├── html
  │   └── index.php

 

Для проверки связи контейнеров, вот пример на PHP, который создает таблицу в базе данных PostgreSQL, заполняет ее случайным текстом и выводит этот текст на экран в браузере:

Terminal:



<h1>Да php работает</h1> <?php phpinfo(); ?>

<?php
$host = 'db';
$port = '5432';
$user = 'docker';
$password = 'dockerpassword';
$database = 'base_docker';

$dsn = "pgsql:host=$host;port=$port;dbname=$database";
$conn = new PDO($dsn, $user, $password);

// Выполните нужные вам действия с соединением к базе данных PostgreSQL



$dsn = "pgsql:host=$host;port=$port;dbname=$database;user=$user;password=$password";

try {
   $conn = new PDO($dsn);
   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   echo "Connected to the PostgreSQL database successfully<br><br>";

   // Создание таблицы
   $sql = "CREATE TABLE IF NOT EXISTS random_text (
       id serial PRIMARY KEY,
       text VARCHAR(255) NOT NULL
   )";
   $conn->exec($sql);
   echo "Table 'random_text' created successfully<br><br>";

   // Заполнение таблицы случайным текстом
   for ($i = 1; $i <= 10; $i++) {
       $randomText = generateRandomText();
       $sql = "INSERT INTO random_text (text) VALUES ('$randomText')";
       $conn->exec($sql);
       echo "Inserted random text: $randomText<br>";
   }

   // Вывод текста из базы данных на экран
   $sql = "SELECT * FROM random_text";
   $result = $conn->query($sql);
   $rows = $result->fetchAll(PDO::FETCH_ASSOC);
   if (count($rows) > 0) {
       echo "<br>Random Text:<br>";
       foreach ($rows as $row) {
           echo $row['text'] . "<br>";
       }
   } else {
       echo "No random text found";
   }
} catch (PDOException $e) {
   echo "Connection failed: " . $e->getMessage();
}

$conn = null;

// Функция для генерации случайного текста
function generateRandomText($length = 20) {
   $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
   $randomText = '';

   for ($i = 0; $i < $length; $i++) {
       $randomText .= $characters[rand(0, strlen($characters) - 1)];
   }

   return $randomText;
}



?>

Приведенный пример создает таблицу 'random_text' с двумя столбцами: 'id' (идентификатор) и 'text' (текстовое поле). Затем он заполняет таблицу случайным текстом, используя функцию generateRandomText(). Наконец, он извлекает текст из базы данных и выводит его на экран в браузере.

Перед использованием этого примера необходимо заменить значения "имя_базы_данных", "имя_пользователя" и "пароль" на соответствующие данные вашей базы данных PostgreSQL, т.е. здесь будут использоваться те данные, что были указаны в docker-compose.yaml при создании второго контейнера. Убедитесь, что у вас есть соединение с базой данных для выполнения примера. Также учтите, что данное решение для базы данных PostgreSQL, и вам понадобится установленный драйвер PHP для работы с PostgreSQL, о чём мы уже тоже позаботились при создании образа из Dockerfile.

После приведения своего рабочего каталога в такой вид, находясь в корне проекта, т.е. в том же каталоге, же где и файл docker-compose.yaml

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


sudo docker-compose pull

Создадим контейнеры из этих образов и запустим их, следующей командой:


sudo docker-compose up -d

Убедимся, что контейнеры запустились успешно:


sudo docker ps -a

Ну и понятное дело, что если вы откроете в браузере домен в моём случае это http://ramanzes.freemyip.com, ну или localhost, который вы указали в образе php при создании web сервера, вы увидете свой сервер в работе.

Свежие статьи

docker-compose пример стека apache2, php, mysql, phpmyadmin, и проксирование nginx
23
июнь

docker-compose пример стека apache2, php, mysql, phpmyadmin, и проксирование nginx

Создадим с помощью Docker Compose ещё один пример, довольно часто используемый стек: сервер apache2 с php, базой данных на mysql, и контейнер для управления базой с помощью phpmyadmin, а также настроим прокси на nginx ещё в одном отдельном контейнере, чтобы было удобно всем этим пользоваться. Таким образом мы увидим всю логику происходящего, для создания подобных конфигураций, для собственных нужд.

Прочитать
docker-compose пример стека apache2+wsgi, python+django, mysql, phpmyadmin, и проксирование nginx
23
июнь

docker-compose пример стека apache2+wsgi, python+django, mysql, phpmyadmin, и проксирование nginx

Создадим с помощью Docker Compose ещё один пример, весьма полезный стек, для Django разработчиков: apache2+wsgi, python+django, mysql, phpmyadmin, и проксирование nginx с базой данных на mysql, и контейнер для управления базой с помощью phpmyadmin, а также настроим прокси на nginx ещё в одном отдельном контейнере, чтобы было удобно всем этим пользоваться. Таким образом мы увидим всю логику происходящего, для создания подобных конфигураций, для собственных нужд.

Прочитать

крипто-донат, на развитие сайта itdid.ru:

В новом окне с терминалом itdid.ru, введите любую сумму: