---
title: 'Автоматизация установки серверов баз данных в Docker с интеграцией в HestiaCP и phpMyAdmin | Zomro'
description: 'В этой статье рассматривается, как развернуть сервера MySQL и MariaDB в контейнерах Docker, используя автоматический скрипт.'
image: 'https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/dalle-2024-11-01-194100-create-a-rectangular-infographic-titled-_docker-hestiacp-phpmyadmin_-setup-guide_-use-a-neon-gradient-color-scheme-with-purple-pink-and-blue-to_q50.jpg'
---

![opened image]()

  * [Zomro](https://zomro.com/rus/)
  * [FAQ](https://zomro.com/rus/blog/faq/)
  * Автоматизация установки серверов баз данных в Docker с интеграцией в HestiaCP и phpMyAdmin 



# Автоматизация установки серверов баз данных в Docker с интеграцией в HestiaCP и phpMyAdmin

30-10-2024

![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/dalle-2024-11-01-194100-create-a-rectangular-infographic-titled-_docker-hestiacp-phpmyadmin_-setup-guide_-use-a-neon-gradient-color-scheme-with-purple-pink-and-blue-to_q50.jpg)

Ручная установка и настройка серверов баз данных может отнять много времени, особенно если речь идет о множественных экземплярах с разными версиями. Автоматизация этого процесса значительно упростит жизнь системному администратору и сэкономит его рабочие часы. В этой статье рассматривается, как развернуть сервера MySQL и MariaDB в контейнерах Docker, используя автоматический скрипт. Этот скрипт также интегрирует базы данных в панель HestiaCP и phpMyAdmin, делая их доступными для управления и взаимодействия с веб-интерфейсом.

**Скрипт, предложенный ниже, автоматизирует следующие задачи:**

  * Проверка и установка Docker и Docker Compose (если они не установлены).
  * Создание контейнеров баз данных с выбранной версией MySQL или MariaDB: **MySQL (5.7 и 8.0)** **MariaDB (10.8, 10.9 и 10.11).**
  * Настройка контейнеров для интеграции с HestiaCP и phpMyAdmin.
  * Удаление контейнеров и связанных с ними данных и конфигураций при необходимости.



**Предупреждение:**

**Этот скрипт предназначен для автоматизации развертывания серверов баз данных в контейнерах Docker и предназначен для опытных пользователей. Все действия выполняются с учетом особенностей и стандартных конфигураций, однако, перед его применением рекомендуется внимательно ознакомиться с логикой скрипта и протестировать его на тестовой среде.**

**Пожалуйста, убедитесь, что все данные и конфигурации, затронутые скриптом, сохранены или зарезервированы. Использование этого скрипта предполагает ответственность пользователя за его применение, и любые действия, связанные с внесением изменений в существующие конфигурации, выполняются на собственный страх и риск.**

​​​​​​​
    
    
    #!/bin/bash
    
    # Log file location
    LOG_FILE="/home/db_installation.log"
    
    # Logging function
    log() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
    }
    
    sed -i 's/^#precedence ::ffff:0:0\/96  10/precedence ::ffff:0:0\/96  100/' /etc/gai.conf
    
    # Function to generate a random password
    generate_password() {
        tr -dc A-Za-z0-9 </dev/urandom | head -c 16
    }
    
    # Function to check for an existing container
    check_existing_container() {
        local db_version=$1
        if [ "$(docker ps -a --filter "name=${db_version}" --filter "label=zomro_add_db" --format '{{.Names}}')" ]; then
            log "Container named ${db_version} with the zomro_add_db flag is already running. Removing existing container..."
            docker rm -f ${db_version}
        fi
    }
    
    # Function to remove a container by version
    remove_container() {
        local db_version=$1
        if [ "$(docker ps -a --filter "name=${db_version}" --filter "label=zomro_add_db" --format '{{.Names}}')" ]; then
            log "Removing container named ${db_version} with the zomro_add_db flag..."
            docker rm -f ${db_version}
            rm -rf /var/lib/${db_version}
            rm -rf /root/docker_${db_version}
            remove_phpmyadmin_config $db_version
            remove_hestia_mysql_config $db_version
            log "Container ${db_version} and related data removed."
        else
            log "No container named ${db_version} with the zomro_add_db flag found."
        fi
    }
    
    # Function to remove the corresponding HestiaCP MySQL configuration entry from mysql.conf using sed
    remove_hestia_mysql_config() {
        local db_version=$1
        local hestia_config_file="/usr/local/hestia/conf/mysql.conf"
    
        if [ -f "$hestia_config_file" ]; then
            cp "$hestia_config_file" "${hestia_config_file}.bak"
            log "Backup of HestiaCP MySQL configuration created: ${hestia_config_file}.bak"
    
            # Exact deletion of a line with the HOST identifier
            sed -i "/HOST='${db_version}'/d" "$hestia_config_file"
    
            log "Removed HestiaCP MySQL configuration entry for ${db_version}."
        else
            log "HestiaCP MySQL configuration file not found."
        fi
    }
    
    # Function to remove the corresponding phpMyAdmin configuration entry
    remove_phpmyadmin_config() {
        local db_version=$1
        local config_file="/etc/phpmyadmin/conf.d/01-${db_version}.php"
    
        if [ -f "$config_file" ]; then
            rm -f "$config_file"
            log "Removed phpMyAdmin configuration for ${db_version} located at ${config_file}."
        else
            log "No phpMyAdmin configuration found for ${db_version}."
        fi
    }
    
    
    # Function to check if Docker is installed
    check_docker_installed() {
        if ! command -v docker &> /dev/null; then
            log "Docker is not installed. Installing Docker..."
            curl -fsSL https://get.docker.com -o get-docker.sh
            sh get-docker.sh
            systemctl start docker
            systemctl enable docker
        else
            log "Docker is already installed."
        fi
    }
    
    # Function to check if Docker Compose is installed
    check_docker_compose_installed() {
        if ! command -v docker-compose &> /dev/null; then
            log "Docker Compose is not installed. Installing Docker Compose..."
    
    
            OS=$(uname -s | tr '[:upper:]' '[:lower:]')
            ARCH=$(uname -m)
    
            if [ "$ARCH" = "x86_64" ]; then
                ARCH="x86_64"
            elif [ "$ARCH" = "aarch64" ]; then
                ARCH="aarch64"
            else
                log "Unsupported architecture: $ARCH"
                exit 1
            fi
    
            # Link to the desired version of Docker Compose
            VERSION="v2.25.0"
            DOCKER_COMPOSE_URL="https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-${OS}-${ARCH}"
    
            # Download and install Docker Compose
            curl -L "$DOCKER_COMPOSE_URL" -o /usr/local/bin/docker-compose
            chmod +x /usr/local/bin/docker-compose
    
            # Checking the installation
            if command -v docker-compose &> /dev/null; then
                log "Docker Compose installed successfully."
            else
                log "Failed to install Docker Compose."
                exit 1
            fi
        else
            log "Docker Compose is already installed."
        fi
    }
    
    
    # Function to add phpMyAdmin configuration for a specific database version
    add_phpmyadmin_config() {
        local db_version=$1
        local port=$2
        local config_file="/etc/phpmyadmin/conf.d/01-${db_version}.php"
    
        log "Creating phpMyAdmin configuration for ${db_version} on port ${port}..."
        cat << EOF > "$config_file"
    <?php
    \$cfg['Servers'][\$i]['host'] = '${db_version}';
    \$cfg['Servers'][\$i]['port'] = '${port}';
    \$cfg['Servers'][\$i]['auth_type'] = 'cookie';
    \$cfg['Servers'][\$i]['verbose'] = '${db_version}';
    
    // Session termination settings
    \$cfg['LoginCookieValidity'] = 1440;
    \$cfg['LoginCookieStore'] = 0;
    \$cfg['ShowPhpInfo'] = true;
    
    // Interface additional settings
    \$cfg['ShowChgPassword'] = true;
    \$cfg['ShowDbStructureCharset'] = true;
    \$cfg['ShowDbStructureCreation'] = true;
    \$cfg['ShowDbStructureLastUpdate'] = true;
    \$cfg['ShowDbStructureLastCheck'] = true;
    
    // Memory and runtime settings
    \$cfg['MemoryLimit'] = '512M';
    \$cfg['ExecTimeLimit'] = 300;
    \$cfg['UploadDir'] = '';
    \$cfg['SaveDir'] = '';
    EOF
    
        # root:www-data for config_file
        chmod 640 "$config_file"
        chown root:www-data "$config_file"
    
        log "phpMyAdmin configuration for ${db_version} added at ${config_file}."
    }
    
    # Checking if Docker is installed
    check_docker_installed
    
    # Checking if Docker Compose is installed
    check_docker_compose_installed
    
    # Generate passwords
    MYSQL_ROOT_PASSWORD=$(generate_password)
    
    # Prompting the user to select an action
    echo "Select an action:"
    echo "1) Install a MySQL/MariaDB server"
    echo "2) Remove an existing MySQL/MariaDB server"
    read -p "Enter the number corresponding to your choice: " action_choice
    
    if [ "$action_choice" -eq 1 ]; then
        log "Prompting the user to select a database version to install..."
        echo "Select the database version to install:"
        echo "1) MySQL 5.7"
        echo "2) MySQL 8.0"
        echo "3) MariaDB 10.8"
        echo "4) MariaDB 10.9"
        echo "5) MariaDB 10.11"
        read -p "Enter the number corresponding to your choice: " db_choice
    
        case $db_choice in
            1)
                DB_IMAGE="mysql:5.7.44-oraclelinux7"
                DB_VERSION="mysql-5.7"
                DB_TYPE="mysql"
                ;;
            2)
                DB_IMAGE="mysql:8.0"
                DB_VERSION="mysql-8.0"
                DB_TYPE="mysql"
                ;;
            3)
                DB_IMAGE="mariadb:10.8"
                DB_VERSION="mariadb-10.8"
                DB_TYPE="mariadb"
                ;;
            4)
                DB_IMAGE="mariadb:10.9"
                DB_VERSION="mariadb-10.9"
                DB_TYPE="mariadb"
                ;;
            5)
                DB_IMAGE="mariadb:10.11"
                DB_VERSION="mariadb-10.11"
                DB_TYPE="mariadb"
                ;;
            *)
                log "Invalid choice. Installation aborted."
                exit 1
                ;;
        esac
    
        check_existing_container $DB_VERSION
    
        if ! grep -q "${DB_VERSION}" /etc/hosts; then
            echo "127.0.0.1 ${DB_VERSION}" >> /etc/hosts
            log "Added hostname ${DB_VERSION} to /etc/hosts"
        fi
    
        log "Creating Docker Compose configuration..."
        AVAILABLE_PORT=3306
        while ss -tuln | grep -q ":$AVAILABLE_PORT"; do
            AVAILABLE_PORT=$((AVAILABLE_PORT + 1))
        done
        mkdir -p /root/docker_${DB_VERSION}
    
        if [ "$DB_TYPE" = "mysql" ] && [ "$DB_VERSION" = "mysql-8.0" ]; then
            cat << EOF > /root/docker_${DB_VERSION}/init.sql
    ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD';
    CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    EOF
    
            cat << EOF > /root/docker_${DB_VERSION}/docker-compose.yml
    services:
      ${DB_VERSION}:
        image: $DB_IMAGE
        container_name: ${DB_VERSION}
        ports:
          - "${AVAILABLE_PORT}:3306"
        environment:
          MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
        command: --default-authentication-plugin=mysql_native_password --bind-address=0.0.0.0
        volumes:
          - /var/lib/${DB_VERSION}:/var/lib/mysql
          - /root/docker_${DB_VERSION}/init.sql:/docker-entrypoint-initdb.d/init.sql
        restart: always
        labels:
          zomro_add_db: "true"
    EOF
    
        else
            if [ "$DB_TYPE" = "mysql" ]; then
                cat << EOF > /root/docker_${DB_VERSION}/init.sql
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    EOF
            elif [ "$DB_TYPE" = "mariadb" ]; then
                cat << EOF > /root/docker_${DB_VERSION}/init.sql
    CREATE OR REPLACE USER 'root'@'%' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    EOF
            fi
    
            cat << EOF > /root/docker_${DB_VERSION}/docker-compose.yml
    services:
      ${DB_VERSION}:
        image: $DB_IMAGE
        container_name: ${DB_VERSION}
        ports:
          - "${AVAILABLE_PORT}:3306"
        environment:
          MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
          MYSQL_ROOT_HOST: '%'
        command: --bind-address=0.0.0.0
        volumes:
          - /var/lib/${DB_VERSION}:/var/lib/mysql
          - /root/docker_${DB_VERSION}/init.sql:/docker-entrypoint-initdb.d/init.sql
        restart: always
        labels:
          zomro_add_db: "true"
    EOF
    
        fi
    
        if [ -d "/var/lib/${DB_VERSION}" ]; then
            BACKUP_DIR="/var/lib/${DB_VERSION}_backup_$(date +%Y%m%d%H%M%S)"
            mv /var/lib/${DB_VERSION} $BACKUP_DIR
            log "Backup created: ${BACKUP_DIR}"
        else
            log "Data directory not found. Skipping backup creation."
        fi
    
        rm -rf /var/lib/${DB_VERSION}
    
        log "Starting Docker Compose for ${DB_VERSION}..."
        docker-compose -f /root/docker_${DB_VERSION}/docker-compose.yml up -d
    
        log "Waiting for the database to be ready..."
        RETRIES=30
        for i in $(seq 1 $RETRIES); do
            if docker exec ${DB_VERSION} mysql -u root -p$MYSQL_ROOT_PASSWORD -e "SELECT VERSION();" >/dev/null 2>&1; then
                log "Database is ready."
                break
            else
                log "Database is not ready yet. Retrying in 5 seconds..."
                sleep 10
            fi
            if [ "$i" -eq "$RETRIES" ]; then
                log "Failed to connect to the database after $RETRIES attempts."
                exit 1
            fi
        done
    
        log "Adding database access to HestiaCP..."
        v-add-database-host mysql ${DB_VERSION} root $MYSQL_ROOT_PASSWORD '' '' '' $AVAILABLE_PORT
    
        add_phpmyadmin_config "${DB_VERSION}" "${AVAILABLE_PORT}"
    
        RED='\033[0;31m'
        NC='\033[0m'
    
        log "Installation of ${DB_VERSION} server completed successfully."
        echo -e "${RED}"
        echo "==========================================="
        echo "            ACCESS DETAILS"
        echo "-------------------------------------------"
        echo "Host: ${DB_VERSION}"
        echo "Port: $AVAILABLE_PORT"
        echo "User: root"
        echo "Password: $MYSQL_ROOT_PASSWORD"
        echo "==========================================="
        echo -e "${NC}"
    
    elif [ "$action_choice" -eq 2 ]; then
        log "Prompting the user to select a database version to remove..."
        echo "Select the database version to remove:"
        echo "1) MySQL 5.7"
        echo "2) MySQL 8.0"
        echo "3) MariaDB 10.8"
        echo "4) MariaDB 10.9"
        echo "5) MariaDB 10.11"
        read -p "Enter the number corresponding to your choice: " db_remove_choice
    
        case $db_remove_choice in
            1)
                DB_VERSION="mysql-5.7"
                ;;
            2)
                DB_VERSION="mysql-8.0"
                ;;
            3)
                DB_VERSION="mariadb-10.8"
                ;;
            4)
                DB_VERSION="mariadb-10.9"
                ;;
            5)
                DB_VERSION="mariadb-10.11"
                ;;
            *)
                log "Invalid choice. Removal aborted."
                exit 1
                ;;
        esac
    
        remove_container $DB_VERSION
    
    else
        log "Invalid action. Exiting."
        exit 1
    fi
    
    exit 0

**Подготовка к автоматизации**

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

**Порядок выполнения скрипта**

  
**Установка Docker и Docker Compose**

  * Сначала скрипт проверяет, установлены ли Docker и Docker Compose. Если нет — производит их загрузку и установку, активирует службу Docker и настраивает автоматический запуск.
  * Эта проверка исключает необходимость вручную отслеживать наличие нужных утилит на сервере, что особенно полезно для администраторов, работающих с множественными системами или версиями ОС.



**Генерация и удаление контейнеров для MySQL и MariaDB**

  * Скрипт предоставляет интерфейс для выбора версии сервера баз данных: **MySQL (5.7 и 8.0)** или **MariaDB (10.8, 10.9 и 10.11).**
  * После выбора версии происходит генерация Docker Compose конфигурации, с которой и запускается контейнер.
  * Если контейнер с данным именем уже существует, скрипт удаляет его, что помогает избежать конфликтов версий и ошибок при развертывании.
  * Для каждой версии создается отдельный файл и уникальный порт для подключения, а также резервная копия папки данных в случае существования предыдущих данных.



![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/2_Klh0Pnk_q50.jpg)

**Создание и настройка конфигурации phpMyAdmin**

  * После успешного создания контейнера скрипт добавляет конфигурацию для phpMyAdmin, чтобы база данных была доступна для администрирования через веб-интерфейс.
  * Конфигурация включает параметры доступа: хост, порт и метод аутентификации.
  * Устанавливаются дополнительные настройки, такие как лимиты времени выполнения запросов и использование cookie для аутентификации, что добавляет гибкость в работе с phpMyAdmin.



![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/3_vSq3oTy_q50.jpg)

![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/4_1ydfrcS_q50.jpg)

**Добавление конфигурации в HestiaCP**

  * HestiaCP, будучи популярной панелью управления, требует интеграции с базами данных для более простого управления ими. Скрипт добавляет хост базы данных в конфигурационный файл HestiaCP, делая его доступным для приложений и пользователей панели.
  * Для этого скрипт использует команду v-add-database-host, которая добавляет запись в HestiaCP и назначает ей порт, выбранный при создании контейнера. Таким образом, вам не придется добавлять базы данных вручную — все конфигурации добавляются автоматически.



![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/5_tvfeSvz_q50.jpg)

**Интерфейс выбора действий (установка или удаление)**

  * После выполнения всех проверок и установок скрипт предлагает интерфейс выбора: установить новый сервер базы данных или удалить уже существующий.
  * При выборе удаления скрипт удаляет контейнер и связанные с ним конфигурационные файлы, а также очищает данные в HestiaCP и phpMyAdmin. Удаление происходит аккуратно: сначала проверяются существующие записи, затем они безопасно удаляются.



![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/6_dTSwJmn_q50.jpg)

![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/8_H6McTL6_q50.jpg)​​​​​​​

**Вывод учетных данных**

По завершении установки скрипт выводит доступ к базе данных:

  * IP-адрес,
  * порт,
  * имя пользователя,
  * пароль.



![](https://dx86q6oq7ry0e.cloudfront.net/uploads/blog/a48%40server-panel.net/2024/11/01/7_rih1gVk_q50.jpg)

Эта информация позволяет быстро приступить к работе, не тратя времени на поиск учетных данных в системе.

**Заключение**

  
Используя данный скрипт, вы можете автоматизировать процесс установки баз данных в Docker, не отвлекаясь на ручные операции. Это решение подходит для различных сценариев, начиная от тестовых окружений до развертывания баз данных в производственных средах. Скрипт также может быть расширен для работы с другими версиями или типами баз данных, что делает его удобным и универсальным инструментом для системного администратора.

Также предлагаем рассмотреть другие полезные статьи: 

  * [Как установить Nginx в Docker-Compose](https://zomro.com/rus/blog/faq/317-kak-ustanovit-nginx-v-docker-compose)
  * [Как скопировать данные с хоста в Docker и из Docker на хост](https://zomro.com/rus/blog/faq/284-kak-skopirovat-dannye-s-hosta-v-docker-i-iz-docker-na-host)
  * [Как подключиться к Docker контейнеру по sFTP](https://zomro.com/rus/blog/faq/306-how-to-connect-to-a-docker-container-via-sftp)



Похожие статьи

[Как создать и подключиться по sFTP дополнительному пользователю](https://zomro.com/rus/blog/faq/305-kak-podkljuchitsja-po-sftp-ljubomu-drugomu-polzovatelju) [TCP и UDP для новичков: простое объяснение](https://zomro.com/rus/blog/faq/672-tcp-and-udp-for-beginners-a-simple-explanation) [Как создать телеграм бота для мониторинга Mikrotik, размещенного за NAT провайдера](https://zomro.com/rus/blog/faq/323-how-to-create-a-telegram-bot-for-monitoring-mikrotik-located-behind-a-nat) [Оптимизация работы виртуальных машин на базе KVM в Linux](https://zomro.com/rus/blog/faq/609-optimizing-kvm-based-virtual-machine-performance-in-linux) [Бекапы с переносом сайтов на серверах VestaCP/HestiaCP через mount](https://zomro.com/rus/blog/faq/385-backups-with-site-transfer-on-vestacphestiacp-servers-via-mount)

[ Выделенные серверы от €88.80/мес ](/rus/dedicated-servers)
