Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 2. Mysql.

Опубликовано admin - вт, 10/01/2024 - 11:53
Docker Swarm

Продолжаем настройку кластера swarm.  
В этой статье мы попробуем добавить сервер mysql к уже существующему стэку Docker Swarm.
Для правильного понимания статьи, необходимо ознакомится с её первой частью ссылка.
Итак, ранее мы развернули наше приложение в Docker Swarm совместно с Nginx, PHP. Дальше без mysql невозможно работать. 
Поэтому, нам необходим обновленный образ (image) Docker для PHP, который будет содержать расширения для работы с базой данной и образ Mysql.
Итак, перейдем в директорию 

cd /root/swarmtest/
vi docker-compose.yml

добавим к уже существующим секциям:

database:                                                                                                                                                                                                                                                                                                              
      container_name: database                                                                                                                                                                                                                                                                                             
      image: mysql                                                                                                                                                                                                                                                                                                         
      restart: always                                                                                                                                                                                                                                                                                                      
      environment:                                                                                                                                                                                                                                                                                                         
        MYSQL_ROOT_PASSWORD: my-secret-pw                                                                                                                                                                                                                                                                                  
        MYSQL_ROOT_HOST: "%"                                                                                                                                                                                                                                                                                               
        MYSQL_DATABASE: swtest_docker                                                                                                                                                                                                                                                                                      
        MYSQL_USER: swtest                                                                                                                                                                                                                                                                                                 
        MYSQL_PASSWORD: swtest                                                                                                                                                                                                                                                                                             
      ports:                                                                                                                                                                                                                                                                                                               
        - '4307:3306'                                                                                                                                                                                                                                                                                                      
      deploy:                                                                                                                                                                                                                                                                                                              
         replicas: 1                                                                                                                                                                                                                                                                                                       
         placement:                                                                                                                                                                                                                                                                                                        
              constraints:                                                                                                                                                                                                                                                                                                 
                  - "node.labels.TAG==prod"                                                                                                                                                                                                                                                                                
      volumes:                                                                                                                                                                                                                                                                                                             
        - ./data/mysql:/var/lib/mysql

Этот код добавит последнюю версию mysql в ваш docker swarm стэк.
Единственное, я добавил новый ярлык к одному из серверов «node.labels.TAG==prod», как это делать описано в первой части – ссылка.

Так же необходим новый образ для PHP:

php:                                                                                                                                                                                                                                                                                                                   
        image: docker-test_php:latest                                                                                                                                                                                                                                                                                      
        ports:                                                                                                                                                                                                                                                                                                             
          - 9001:9001                                                                                                                                                                                                                                                                                                      
        deploy:                                                                                                                                                                                                                                                                                                            
            replicas: 2                                                                                                                                                                                                                                                                                                    
            resources:                                                                                                                                                                                                                                                                                                     
              limits:                                                                                                                                                                                                                                                                                                      
                cpus: '0.1'                                                                                                                                                                                                                                                                                                
                memory: 200M                                                                                                                                                                                                                                                                                               
        volumes:                                                                                                                                                                                                                                                                                                           
          #- /mnt:/var/www                                                                                                                                                                                                                                                                                                 
           - /gluster/volume1/www:/var/www 

На локальном хосте у меня имелся готовый php образ «docker-test_php:latest».
Вы можете создать его на локальном хосте, затем экспортировать на сервер и импортировать в docker на хосте manager к уже существующим образам (image). 
Вот файл, из которого собирался образ «docker-test_php:latest»:
 

FROM php:8.2-fpm

RUN apt update \
&& apt install -y zlib1g-dev g++ git libicu-dev zip libzip-dev libmagickwand-dev libmagickcore-dev \
libxml2-dev \ 
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install intl opcache pdo pdo_mysql gd soap \
&& pecl install apcu \
&& docker-php-ext-enable apcu \
&& docker-php-ext-configure zip \
&& docker-php-ext-install zip \
&& docker-php-ext-install exif \
&& pecl install imagick \
&& docker-php-ext-enable imagick \
&& docker-php-ext-install sysvmsg \
&& docker-php-ext-install sysvsem \
&& docker-php-ext-install sysvshm \
&& docker-php-ext-configure sysvmsg --enable-sysvmsg \
&& docker-php-ext-configure sysvsem --enable-sysvsem \
&& docker-php-ext-configure sysvshm --enable-sysvshm

RUN cd /usr/local/etc/php/conf.d/ && \
echo 'memory_limit = -1' >> /usr/local/etc/php/conf.d/docker-php-ram-limit.ini
RUN apt-get update && apt-get install -y nodejs \
-y npm \
&& npm install --global yarn

WORKDIR /var/www/docker-test

Команда экспорта образа docker:

docker save -o <filename>.tar <image_name>

Команда импорта:

docker load < my-php-container.tar

После того как вы добавили этот образ на manager хост, можно убедиться в этом командой:

docker image list (docker images)

Для удаления стэка

docker stack rm swarmtest

Для запуска стэка (необходимо находится в той же директории что и файл docker-compose.yml)

docker stack deploy --compose-file docker-compose.yml

Для добавления mysql необходимо создать таблицу.   
Для настройки авторизации на сервере mysql:      

environment:                                                                                                                                                                                                                                                                                                         
        MYSQL_ROOT_PASSWORD: my-secret-pw                                                                                                                                                                                                                                                                                  
        MYSQL_ROOT_HOST: "%"                                                                                                                                                                                                                                                                                               
        MYSQL_DATABASE: swtest_docker                                                                                                                                                                                                                                                                                      
        MYSQL_USER: swtest                                                                                                                                                                                                                                                                                                 
        MYSQL_PASSWORD: swtest     

   Не забывайте, что проверить где находится сервис можно используя команду «docker conatainer ls»:     

Docker Swarm

Давайте зайдем на сервер mysql используя команду:

docker exec -it swarmtest_database.1.yjclod78lq6c6ak0z4uu0a4mt bash
Docker Swarm

Сейчас в базе данных swtest_docker нет таблиц. Пароль root у нас исходя из настроек “my-secret-pw”. Вам будет предложено ввести временный пароль. Используйте тот, который вы указали в переменной окружения MYSQL_ROOT_PASSWORD.

Создадим одну таблицу.

CREATE TABLE `Staff` (
  `id` int DEFAULT NULL,
  `name` varchar(255) NOT NULL,
  `position` varchar(30) DEFAULT NULL,
  `birthday` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Внесём данные:

LOCK TABLES `Staff` WRITE;
INSERT INTO `Staff` VALUES (1,'Alex','2','2024-09-26');
UNLOCK TABLES;

Сейчас вам станет доступным вывод из mysql из скрипта index.php.

<?php
echo '<html><head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">

</head>
<body><div class="container">';
echo '<h2>Hello title</h2>';

echo '<p>Hello body <br/>';

echo '<p style="float:left;">
<img src="http://eapsite.ru/benjamin-voros-phIFdC6lA4E-unsplash.jpg" alt="Featued image for: Tutorial: Deploy a Full-Stack Application to a Docker Swarm" width="620" height="414"></p>
';

try {
    $dbh = new PDO('mysql:dbname=swtest_docker;host=0.0.0.0:4307', 'swtest', 'swtest');
} catch (PDOException $e) {
    die($e->getMessage());
}
$sth = $dbh->prepare("SELECT * FROM `Staff` WHERE `id` = ?");
$sth->execute(array('1'));
$array = $sth->fetch(PDO::FETCH_ASSOC);

function getUserIP()
{
    // Get real visitor IP behind CloudFlare network
    if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
              $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
              $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
    }
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];
    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }
    return $ip;
}


$user_ip = getUserIP();
echo '<div style="clear:both;"><h2>Mysql</h2></div>';
echo '<br/>';

echo $user_ip; // Output IP address [Ex: 177.87.193.134]
//
echo '<br/>';
echo 'id ' . $array['id'] . '<br/>';
echo 'name ' .  $array['name'] . '<br/>';
echo 'birthday  ' . $array['birthday'] . '<br/>';

echo '<pre>';
print_r($_SERVER);
echo '</pre>';
echo '</div></body></html>

Скрипт имеет много лишнего. Но мы постараемся объяснить зачем это в нём содержится в следующей статье, в которой добавим прокси сервер "Traefik" ко всему ранее созданному и настроим его для совместной работы с Docker Swarm.

После этого, у Вас должна отображаться примерно следующая страница:

Docker Swarm

Взаимосвязанные материалы

# 1. Типичный пример Docker с Nginx и SSL (воскресенье, октября 6, 2024 - 15:33 ),
Типичный пример быстрой настройки Docker и Nginx c доступом по https. читать...
# 2. Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 4. Traefik и SSL Let's Encrypt: TLS (пятница, октября 4, 2024 - 23:31 ),

Небольшая статья - продолжение предыдущих трёх статей:

читать...
# 3. Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 3. Traefik. (четверг, октября 3, 2024 - 12:35 ),
Продолжаем настройку кластера Swarm. В этой статье мы попробуем добавить Traefik к уже существующему стэку Docker Swarm. читать...
# 4. Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 2. Mysql. (вторник, октября 1, 2024 - 11:53 ),
Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 2. Mysql. В этой статье мы попробуем добавить сервер mysql к уже существующему стэку Docker Swarm. читать...
# 5. Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 1. (понедельник, сентября 23, 2024 - 14:57 ),
С помощью Docker можно быстро развернуть рабочее web приложение с различными настройками и версиями. Docker Swarm выступает инструментом «оркестрации» контейнеров Docker, который позволяет управлять контейнерами как единое целое. читать...
На разработку сайта! Скидки до 20%!