Bootstrap

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

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

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

если у вас ещё не установлены 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 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, а не внешний, что у нас тут был бы как 81


    ServerName 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

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


sudo docker-compose pull

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


sudo docker-compose up -d

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


sudo docker ps -a

Ну и понятное дело, что если вы откроете в браузере домен в моём случае это 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 нужно вводить следующие данные исходя из наших настроек

server это db имя контейнера указанное в docker-compose пользователь root и его пароль что тоже указан в docker-compose

Копирование материалов разрешается только с указанием автора Roman Sakhno и индексируемой прямой ссылкой на сайт (http://itdid.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/sahroman.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/sahroman.

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как настроить свой компьютер

  2. Текстовая ссылка:

    Она выглядит вот так: Как настроить свой компьютер

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

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

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

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