Phần 11: Hướng dẫn cài đặt MYSQL trên docker portainer

 

docker

I. Giới thiệu MySQL 8.3

MySQL 8.3 là phiên bản mới của MySQL – một trong những database server phổ biến nhất thế giới. Điều này rất hữu ích khi:

  • Bạn cần database để lưu trữ dữ liệu ứng dụng
  • Muốn chạy MySQL trên Docker thay vì cài trực tiếp
  • Cần quản lý multiple databases cho các ứng dụng khác nhau
  • Muốn backup & restore dữ liệu dễ dàng
  • Cần high performance relational database

Chức năng chính MySQL 8.3:

  • ACID compliance (data integrity)
  • Support foreign keys & constraints
  • Full-text search
  • Transactions (commit/rollback)
  • Replication & clustering
  • Performance schema & monitoring
  • JSON data type
  • Window functions & CTEs

So sánh MySQL 8.3 với các database khác:

Tính năngMySQL 8.3PostgreSQLMariaDB
GiáMiễn phí (open source)Miễn phí (open source)Miễn phí (open source)
PerformanceRất nhanhRất nhanhNhanh (fork của MySQL)
FeaturesCơ bản + JSONAdvanced (PostGIS, …)Tương tự MySQL
CompatibilityHigh (WordPress, Laravel)Cao (khác cơ bản)100% MySQL
Ease of useRất dễTrung bìnhRất dễ

II. Triển khai MySQL 8.3 với Docker

1. Docker Compose

version: '3.8'

services:
  mysql-node-2:
    image: mysql:8.3.0
    container_name: mysql_aio
    restart: always
    ports:
      - "3366:3306"
    environment:
      MYSQL_ROOT_PASSWORD: your_secure_password_here
      MYSQL_MAJOR: innovation
      MYSQL_VERSION: 8.3.0-1.el8
    volumes:
      - /root/mysql-node-2/my.cnf:/etc/my.cnf
      - /root/mysql-node-2/db:/var/lib/mysql
      - /root/mysql-node-2:/root
    mem_limit: 1024m
    cpus: 0.5
    command: mysqld

Giải thích cấu hình:

  • image: mysql:8.3.0 (phiên bản 8.3.0)
  • MYSQL_ROOT_PASSWORD: Mật khẩu root (bắt buộc)
  • ports: 3366 (host) → 3306 (container)
  • volumes: Mount config & data
  • my.cnf: File cấu hình MySQL
  • db: Thư mục lưu trữ databases
  • mem_limit: Giới hạn RAM 1GB
  • cpus: Giới hạn CPU 50%
  • restart: always: Tự động khởi động lại

2. Tạo File my.cnf (Cấu hình MySQL)

Tạo /root/mysql-node-2/my.cnf:

[mysqld]
# Basic configuration
default-storage-engine=InnoDB
collation-server=utf8mb4_unicode_ci
character-set-server=utf8mb4
skip-external-locking

# Connection settings
max_connections=100
connect_timeout=10
wait_timeout=28800

# InnoDB settings
innodb_buffer_pool_size=768M
innodb_log_file_size=256M
innodb_flush_log_at_trx_commit=1

# Query cache (disabled in MySQL 8)
query_cache_type=0

# Logging
log_error=/var/log/mysql/error.log
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2

# Replication (if needed)
server-id=2
log_bin=/var/log/mysql/mysql-bin.log
binlog_format=ROW

3. Deploy qua Portainer

Xem hướng dẫn cài đặt portainer: Phần 1: Portainer là gì? Hướng dẫn quản lý Docker HomeLab toàn diện (2025)

  1. SSH vào server & tạo thư mục:
mkdir -p /root/mysql-node-2/db
touch /root/mysql-node-2/my.cnf
# Paste content từ phần II.2 vào my.cnf
  1. Vào Portainer Dashboard
  2. Chọn StacksAdd stack
  3. Đặt tên Stack: mysql
  4. Copy/paste docker-compose vào Web editor
  5. Thay your_secure_password_here bằng mật khẩu mạnh
  6. Click Deploy the stack

4. Kiểm tra hoạt động

Vào Portainer → Stacks → mysql → Container → mysql_aio → Logs.

Bạn sẽ thấy dòng như:

2024-01-15 10:30:00 0 [System] InnoDB: Buffer pool size set to 768M
2024-01-15 10:30:01 0 [System] InnoDB: Redo log container 0 'ib_redo0'
2024-01-15 10:30:05 0 [System] [MY-011323] Server startup complete

III. Kết nối & Quản lý MySQL

1. Kết nối từ CLI

Kết nối từ host machine:

mysql -h 127.0.0.1 -P 3366 -u root -p
# Nhập password khi được hỏi

2. Tạo Database & User

Sau khi đăng nhập:

-- Tạo database mới
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Tạo user (không phải root)
CREATE USER 'appuser'@'%' IDENTIFIED BY 'app_password_here';

-- Cấp quyền
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'%';

-- Reload privileges
FLUSH PRIVILEGES;

3. Kiểm tra Status

-- Kiểm tra version
SELECT VERSION();

-- Kiểm tra databases
SHOW DATABASES;

-- Kiểm tra users
SELECT User, Host FROM mysql.user;

-- Kiểm tra connections
SHOW PROCESSLIST;

-- Kiểm tra status
SHOW STATUS;

4. Sử dụng MySQL Client Tools

Những tools quản lý MySQL phổ biến:

  • MySQL Workbench: Official tool từ MySQL
  • DBeaver: Universal database client
  • Adminer: Web-based client
  • phpMyAdmin: Web-based cho PHP
  • HeidiSQL: HeidiSQL
  • Navicat: Navicat

IV. Kết nối với các ứng dụng

1. Kết nối từ Docker Container khác

Nếu các container ở cùng network:

Hostname: mysql_aio (hoặc mysql_aio.docker-net)
Port: 3306
Username: root / appuser
Password: (như đã set)

Connection string:

mysql://appuser:password@mysql_aio:3306/myapp

2. Kết nối từ Python

import mysql.connector

conn = mysql.connector.connect(
    host="127.0.0.1",
    port=3366,
    user="appuser",
    password="app_password_here",
    database="myapp"
)

cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()

3. Kết nối từ Node.js

const mysql = require('mysql2/promise');

const connection = await mysql.createConnection({
  host: '127.0.0.1',
  port: 3366,
  user: 'appuser',
  password: 'app_password_here',
  database: 'myapp'
});

const [rows] = await connection.query('SELECT * FROM users');

4. Kết nối từ PHP

$conn = new mysqli(
  "127.0.0.1:3366",
  "appuser",
  "app_password_here",
  "myapp"
);

if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

$result = $conn->query("SELECT * FROM users");

V. Backup & Restore

1. Backup Database

Backup toàn bộ database:

mysqldump -h 127.0.0.1 -P 3366 -u root -p myapp > myapp_backup.sql

Hoặc từ container:

docker exec mysql_aio mysqldump -u root -p -e --all-databases > backup.sql

2. Backup Định kỳ (Cron)

Tạo script /root/scripts/backup-mysql.sh:

#!/bin/bash
BACKUP_DIR=/root/backups
DATE=$(date +%Y%m%d_%H%M%S)
MYSQL_PASS="your_password"

mkdir -p $BACKUP_DIR

docker exec mysql_aio mysqldump -u root -p"$MYSQL_PASS" --all-databases > $BACKUP_DIR/mysql_$DATE.sql

# Compress
gzip $BACKUP_DIR/mysql_$DATE.sql

# Keep only 7 days
find $BACKUP_DIR -name "mysql_*.sql.gz" -mtime +7 -delete

Chạy hàng ngày (2AM):

0 2 * * * /bin/bash /root/scripts/backup-mysql.sh

3. Restore Database

mysql -h 127.0.0.1 -P 3366 -u root -p myapp < myapp_backup.sql

3. Logging & Monitoring

Bật slow query log để debug:

[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
log_queries_not_using_indexes=1

VII. Troubleshooting

MySQL không khởi động

  • Kiểm tra logs: docker logs mysql_aio
  • Kiểm tra port có conflict không: lsof -i :3366
  • Kiểm tra volume mount đúng chưa
  • Xóa container & tạo mới (mất dữ liệu cũ)

Không thể kết nối

  • Kiểm tra port: nc -zv 127.0.0.1 3366
  • Kiểm tra password có đúng không
  • Kiểm tra user có quyền access không
  • Kiểm trace firewall không block

Performance chậm

  • Kiểm tra slow query log
  • Thêm indexes cho columns thường query
  • Tăng innodb_buffer_pool_size
  • Kiểm tra disk space

Dữ liệu bị mất sau restart

  • Kiểm tra volume mount: /root/mysql-node-2/db:/var/lib/mysql
  • Kiểm tra folder tồn tại & có quyền write
  • Xem logs để tìm lỗi

VIII. Lưu ý quan trọng

  • Mật khẩu root: Giữ kín, không share lên Git. Sử dụng environment variables hoặc secrets manager
  • Port mapping: 3366 (host) để tránh xung đột với MySQL native (3306)
  • Backup dữ liệu: Backup định kỳ để tránh mất dữ liệu
  • Character set: Luôn dùng utf8mb4 để support emoji & Unicode
  • User permissions: Tạo user riêng cho mỗi app, không dùng root
  • Resource limits: Tuning innodb_buffer_pool_size & max_connections
  • Monitoring: Theo dõi slow queries & disk usage
  • Version: MySQL 8.3 khác MySQL 5.7 (mất hỗ trợ query cache, …)

Vậy là bạn đã hoàn thành cấu hình MySQL 8.3 để lưu trữ & quản lý dữ liệu!