Loading 0
Share

My Blog

Scroll Down

How to Dockerize your Virtualmin Like a Pro (Without Losing Your Mind)

How to Dockerize your Virtualmin Like a Pro (Without Losing Your Mind)

So, you want to dockerize Virtualmin? Stop right there! Trying to shove the entire Virtualmin system into a Docker container is a surefire way to fail. Instead, let’s do something smarter—dockerize only the databases. This approach offers a bulletproof setup with isolated database instances, automatic Virtualmin backups, and a disaster recovery plan that actually works.

In this guide, we’ll show you how to run each database in its own MariaDB instance, reducing the risk of total database failure in case of InnoDB corruption or cyberattacks. Bonus: You’ll still have Virtualmin’s UI to manage DNS, email, and everything else.

Why Combine Docker with Virtualmin?

Because, my dear reader, you get the best of both worlds:

  • Isolated databases: Each database runs in its own container with its own MariaDB instance.
  • Scalability: Easily move containers between servers.
  • Security: If one database is hacked, it doesn’t affect others.
  • Virtualmin UI stays intact: Clients can still manage their hosting environment while databases live inside Docker.

 

Step 1: Install Docker, Docker-Compose, and Portainer

First things first, install the required software:

apt update && apt install -y docker.io docker-compose

Then, deploy Portainer for a user-friendly container management experience:

docker run -d -p 9000:9000 --name=portainer --restart=unless-stopped -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer-ce

Access Portainer via http://yourdomain:9000 to easily manage your containers.

 

Step 2: Prepare the Virtualmin Server for Docker

Navigate to your Virtualmin server’s home directory and create a Docker workspace:

cd /home/SERVER_NAME
mkdir docker && cd docker
mkdir mysql database_backups

Step 3: Create a Docker Compose File

Inside the docker folder, create a docker-compose.yml file:

version: '3.8'
services:
  mariadb:
    build: .
    container_name: SERVER_NAME-db
    environment:
      MYSQL_ROOT_PASSWORD: "YOUR_ROOT_PASSWORD"
      MYSQL_DATABASE: "YOUR_DATABASE_NAME"
      MYSQL_USER: "YOUR_DATABASE_USER"
      MYSQL_PASSWORD: "YOUR_DATABASE_PASSWORD"
    volumes:
      - /home/SERVER_NAME/docker/mysql:/var/lib/mysql
    restart: unless-stopped
    networks:
      - SERVER_NAME-db_network

networks:
  SERVER_NAME-db_network:
    driver: bridge

Step 4: Create a Dockerfile

Inside the docker folder, create a Dockerfile:

FROM mariadb:latest
COPY my.cnf /etc/mysql/mariadb.conf.d/50-server.cnf

Step 5: Configure MariaDB

Create a my.cnf file inside the docker folder:


[client]
default-character-set = utf8mb4

[mysqld]
user = mysql
bind-address = 0.0.0.0
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_allowed_packet = 64M
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
tmp_table_size = 256M
max_heap_table_size = 256M
table_open_cache = 8000
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-queries.log
long_query_time = 2

Step 6: Deploy the MariaDB Container

Navigate to your Docker directory and launch the container:

cd /home/SERVER_NAME/docker
docker-compose -f docker-compose.yml -p SERVER_NAME-db up -d

Step 7: Connect Your Application to the Dockerized Database

Get the container’s IP by checking Portainer or running:

docker inspect SERVER_NAME-db | grep "IPAddress"

Edit your WordPress wp-config.php or application database config to use the container’s IP:

define('DB_HOST', '172.XX.XX.XX:3306');

Step 8 (Optional): Set Up Automatic Backups

To ensure your database is safe, use Virtualmin’s built-in backup system:

  • Visit: YOUR_DOMAIN:10000/virtual-server/list_sched.cgi?xnavigation=1
  • Schedule backups to a remote storage.

For an additional backup solution, create a database export script:

nano /home/SERVER_NAME/docker/export_db.sh

Paste the following script:


#!/bin/bash
set -e
BASE_DIR="/home/SERVER_NAME/docker"
BACKUP_DIR="$BASE_DIR/database_backups"
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
RETENTION_DAYS=30
LOG_FILE="$BASE_DIR/cron_log.txt"

mkdir -p "$BACKUP_DIR"
BACKUP_FILE="$BACKUP_DIR/db_backup_$DATE.sql"

CONTAINER_NAME=$(grep -E '^\s*container_name:' "$BASE_DIR/docker-compose.yml" | awk -F': ' '{print $2}' | xargs)
DB_NAME=$(grep -E '^\s*MYSQL_DATABASE:' "$BASE_DIR/docker-compose.yml" | awk -F': ' '{print $2}' | xargs)
DB_USER=$(grep -E '^\s*MYSQL_USER:' "$BASE_DIR/docker-compose.yml" | awk -F': ' '{print $2}' | xargs)
DB_PASSWORD=$(grep -E '^\s*MYSQL_PASSWORD:' "$BASE_DIR/docker-compose.yml" | awk -F': ' '{print $2}' | xargs)

cd "$BASE_DIR" || exit 1
docker exec "$CONTAINER_NAME" mariadb-dump -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$BACKUP_FILE"
tar -czf "$BACKUP_FILE.tar.gz" -C "$BACKUP_DIR" "$(basename "$BACKUP_FILE")"
rm "$BACKUP_FILE"
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $BACKUP_FILE.tar.gz" >> "$LOG_FILE"

Make it executable:

chmod +x /home/SERVER_NAME/docker/export_db.sh

To automate daily backups, create a cron job in Virtualmin:

  • Go to YOUR_DOMAIN:10000/cron/?xnavigation=1
  • Add this command:
/home/SERVER_NAME/docker/export_db.sh >> /home/SERVER_NAME/docker/db_backup_log.txt 2>&1

Extra Tip: Want phpMyAdmin?

Download phpMyAdmin, unzip it in your website directory, and modify config.inc.php to set the container’s IP as the database host.

Conclusion

Congratulations, you’ve successfully dockerized Virtualmin’s databases while keeping the UI intact! This setup enhances security, performance, and scalability while ensuring that every database runs in an isolated container. Now, go enjoy your fully dockerized Virtualmin experience! 🚀

Leave a Reply

Your email address will not be published. Required fields are marked *

01.

Here you can see all the services I provide

Registration and management of domain names (website address such as www.nicolaslagios.com)

Also management of dns records (e.g. connecting the domain to a specific server, fixing email spam problems, etc.)

Also ssl renewals etc

Installation and management of web & mail server in ubuntu vps with virtualmin, plesk, cpanel

Also studying and fixing server problems.

Necessary condition, the target server meets the conditions

At the moment for new wordpress websites you can choose from ready-made themes and we change the content (no custom changes). You can buy with a fixed price by clicking here!

My team and I undertake any data bridging implementation for Wordpress, Prestashop, Opencart, Joomla platforms.

We can connect data from any source, as long as the structure is stable and there is proper documentation and briefing.

We undertake the creation, regulation and enrichment of pages for social networks: Facebook, Linkedin, Instagram (profile), Twitter (profile), Tiktok (profile).

We also undertake the first boost of your pages for quick results in followers.

We undertake the repair and maintenance of your existing wordpress website.

For more information about the services, you can read the following and return here to schedule a meeting with me: https://maxservices.gr/en/internet-services/website-services-blank/additional-website-services/