MySQL Master-Slave(Replica) using docker compose

Requirement:
  • 1 Database – Master server (prefer Linux Ubuntu, VM or Onprem), Docker compose pre-installed.
  • 1 Database – Slave/Replica (prefer Linux Ubuntu, VM or Onprem), Docker compose pre-installed.
  • Network connection between Master-Slave with internet connection for pull MySQL image.
  • Storage space, IOPS, and others refer to your requirement and need.
Directory structure
.
├── docker-compose.yml
├── init.sql
├── master_data
│   ├── digikam
│   ├── mysql
│   ├── performance_schema
│   └── sys
├── mysql_config
│   └── my.cnf
└── mysql_logs

without further ado let’s start.

ssh to Master server and add docker-compose.yml, init.sql to your preferred root folder then create “mysql_config” folder and save my.cnf there “./mysql_config/my.cnf”

# Docker-compose.yml
# Server Master
services:
  mysql-master:
    #for MySQL Community edition: mysql:8.0
    #for MySQL Enterprise edition: container-registry.oracle.com/mysql/enterprise-server:8.0
    image: container-registry.oracle.com/mysql/enterprise-server:8.0 
    container_name: mysql-master
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: MFfj3iXZ1e2F3amqbiFX # Replace with your own password
    ports:
      - "3306:3306"
    volumes:
      - ./master_data:/var/lib/mysql        #expose data to host
      - ./mysql_logs:/var/log               #expose log to host
      - ./mysql_config/my.cnf:/etc/my.cnf   #expose config to host
      - /usr/share/zoneinfo:/usr/share/zoneinfo:ro
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql #exec pre-setup config
    command: --server-id=1 --gtid-mode=ON --enforce-gtid-consistency=ON --max_allowed_packet=128M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"   # Max log size per file 
        max-file: "5"     # max log file to keep
# init.sql
-- Check DB if not exsist then create
CREATE DATABASE IF NOT EXISTS digikam;

-- Create replication user
CREATE USER IF NOT EXISTS 'ReplicationUser'@'%' IDENTIFIED WITH caching_sha2_password BY 'ReplicationPassword';
GRANT REPLICATION SLAVE ON *.* TO 'ReplicationUser'@'%';

-- We not set root account to allow remotely, se we need new for easy setup
CREATE USER IF NOT EXISTS 'YourAdminName'@'%' IDENTIFIED WITH caching_sha2_password BY 'X1GYZjc8aT6TY8ZP1qwA';
GRANT ALL PRIVILEGES ON *.* TO 'YourAdminName'@'%' WITH GRANT OPTION;

-- Sample, Create user for digikam
CREATE USER IF NOT EXISTS 'digikam'@'%' IDENTIFIED WITH mysql_native_password BY 'nLqTf0QeEbZcf103Mzic';
GRANT ALL PRIVILEGES ON *.* TO 'digikam'@'%' WITH GRANT OPTION;

-- Apply perubahan
FLUSH PRIVILEGES;
#./mysql_config/my.cnf 
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html

[mysqld]
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
server-id=1
log_bin=mysql-bin
gtid_mode=ON
enforce_gtid_consistency=ON
innodb_redo_log_capacity = 10G

with evening is setup, lets running docker compose

# sudo docker-compose up -d && sudo docker-compose logs -f

when everting is work you will ending with this log (ctrl+c to stop/exit log tail)

...
mysql-master  | [Entrypoint] MySQL init process done. Ready for start up.
mysql-master  | 
mysql-master  | [Entrypoint] Starting MySQL 8.0.45-1.2.24-server
mysql-master  | 2026-06-05T13:09:50.269447Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.45-commercial) starting as process 1
mysql-master  | 2026-06-05T13:09:50.275298Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
mysql-master  | 2026-06-05T13:09:50.478426Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysql-master  | 2026-06-05T13:09:50.630577Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql-master  | 2026-06-05T13:09:50.630604Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysql-master  | 2026-06-05T13:09:50.656198Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysql-master  | 2026-06-05T13:09:50.656269Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.45-commercial'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MySQL Enterprise Server - Commercial.
mysql-master  | 2026-06-05T13:11:21.956407Z 21 [Warning] [MY-013360] [Server] Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'

Next we will gonna create Slave or replica