Hướng dẫn toàn tập: Cài đặt & quản trị XenForo 2.3 với Docker trên Ubuntu 22.04

Blue

Founder
Thành viên BQT
Tài liệu này cung cấp hướng dẫn từng bước từ cài đặt môi trường ban đầu đến triển khai thực tế, cấu hình tên miền, bảo mật, tối ưu hóa hiệu năng và sao lưu tự động cho XenForo 2.3.

docker-ubuntu.jpg

PHẦN 1: Cài Đặt Docker & Mở Port Trên Ubuntu 22.04​

Kết nối SSH vào VPS Ubuntu 22.04 của bạn bằng quyền root hoặc tài khoản có quyền sudo, sau đó thực hiện các bước sau:

1.1 Cài đặt Docker Engine & Docker Compose​

Chạy tuần tự các lệnh sau để cập nhật hệ thống và tải bộ cài Docker chính thức:
Bash:
# Cập nhật danh sách gói và cài đặt các thư viện cần thiết
sudo apt update && sudo apt upgrade -y
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# Thêm GPG Key chính thức của Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Thêm kho lưu trữ của Docker
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Tiến hành cài đặt Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

1.2 Cấu hình quyền chạy Docker không cần sudo (Khuyên dùng)​

Bash:
sudo usermod -aG docker $USER
newgrp docker

1.3 Mở cổng tường lửa trên VPS​

Bash:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp   # Cho HTTP/3 hỗ trợ tốc độ cao
sudo ufw reload
*(Nếu bạn dùng tường lửa đám mây của nhà cung cấp VPS như AWS, Google Cloud, Contabo,... cần cấu hình mở cổng 80, 443 trên trang quản trị Console của họ).*

PHẦN 2: Thiết Lập Cấu Trúc Dự Án Docker Compose​

Tạo thư mục dự án trên VPS (để bảo mật cao, không đặt tên mặc định lộ liễu, ví dụ đặt tại /home/mx_forum_prod) và tạo các file cấu hình như bên dưới.
Cấu trúc thư mục mong muốn:
Mã:
/home/mx_forum_prod/
├── docker-compose.yml
├── .env
├── app/
│   ├── Dockerfile
│   └── php.ini
├── web/
│   └── Caddyfile
├── db/
│   └── my.cnf
└── src/                 # Thư mục chứa mã nguồn XenForo

2.1 File cấu hình môi trường .env​

Tạo file .env chứa thông tin cấu hình tài khoản database, Redis và thông tin tên miền:
Mã:
# Tên miền website (Đặt là tên miền của bạn, ví dụ: forum.domain.com)
DOMAIN=forum.domain.com
# Múi giờ hệ thống
TZ=Asia/Ho_Chi_Minh
# Thông tin tài khoản Database (Hãy thay đổi mật khẩu an toàn)
DB_ROOT_PASSWORD=K3p8_9xF2_RootSecurePass_zQ1m
DB_DATABASE=db_mx_prod_forum
DB_USER=usr_mx_dbadmin
DB_PASSWORD=Xf_83d_UserSecurePass_7tWp
# Mật khẩu kết nối Redis
REDIS_PASSWORD=Rd_49x_RedisSecurePass_9yLr
# Cấu hình Backup Database hàng ngày
BACKUP_CRON=0 3 * * *         # Chạy tự động lúc 3:00 sáng mỗi ngày
BACKUP_RETAIN_DAYS=7          # Chỉ giữ lại bản backup của 7 ngày gần nhất

2.2 File điều phối dịch vụ docker-compose.yml​

YAML:
services:
  # Database Service (MariaDB)
  db:
    image: mariadb:10.11
    container_name: mx_prod_db
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MARIADB_DATABASE: ${DB_DATABASE}
      MARIADB_USER: ${DB_USER}
      MARIADB_PASSWORD: ${DB_PASSWORD}
      TZ: ${TZ}
    volumes:
      - db_data:/var/lib/mysql
      - ./db/my.cnf:/etc/mysql/conf.d/xenforo.cnf
    networks:
      - xf-network
  # Cache Service (Redis)
  redis:
    image: redis:7-alpine
    container_name: mx_prod_redis
    restart: unless-stopped
    command: redis-server --requirepass "${REDIS_PASSWORD}"
    volumes:
      - redis_data:/data
    networks:
      - xf-network
  # PHP-FPM Service (XenForo Execution Engine)
  app:
    build: ./app
    container_name: mx_prod_app
    restart: unless-stopped
    environment:
      TZ: ${TZ}
    volumes:
      - ./src:/var/www/html
    networks:
      - xf-network
    depends_on:
      - db
      - redis
  # Web Server (Caddy with Auto-SSL and HTTP/3)
  web:
    image: caddy:2-alpine
    container_name: mx_prod_web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    environment:
      DOMAIN: ${DOMAIN}
    volumes:
      - ./web/Caddyfile:/etc/caddy/Caddyfile
      - ./src:/var/www/html
      - caddy_data:/data
      - caddy_config:/config
      - caddy_logs:/var/log/caddy
    networks:
      - xf-network
    depends_on:
      - app
  # Daily Database Backup Service
  db-backup:
    image: fradelg/mysql-cron-backup:latest
    container_name: mx_prod_db_backup
    restart: unless-stopped
    environment:
      MYSQL_HOST: db
      MYSQL_USER: root
      MYSQL_PASS: ${DB_ROOT_PASSWORD}
      CRON_TIME: ${BACKUP_CRON}
      MAX_BACKUPS: ${BACKUP_RETAIN_DAYS}
      GZIP_LEVEL: 9
      TZ: ${TZ}
    volumes:
      - ./backups:/backup
    networks:
      - xf-network
    depends_on:
      - db
  # Database Web Manager (phpMyAdmin)
  # BẢO MẬT CAO: Chỉ cho phép truy cập cục bộ (127.0.0.1).
  # Để đăng nhập, hãy sử dụng SSH Tunneling hoặc đổi thành cổng ngẫu nhiên nếu muốn mở công khai.
  phpmyadmin:
    image: phpmyadmin:latest
    container_name: mx_prod_phpmyadmin
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    environment:
      PMA_HOST: db
      UPLOAD_LIMIT: 1500M
      MEMORY_LIMIT: 2048M
      MAX_EXECUTION_TIME: 3600
    networks:
      - xf-network
    depends_on:
      - db
networks:
  xf-network:
    driver: bridge
volumes:
  db_data:
    driver: local
  redis_data:
    driver: local
  caddy_data:
    driver: local
  caddy_config:
    driver: local
  caddy_logs:
    driver: local

2.3 File app/Dockerfile (Build PHP 8.3 FPM tùy chỉnh)​

Mã:
FROM php:8.3-fpm-alpine
# Cài đặt trình cài đặt extension tự động
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
# Cài đặt toàn bộ các extension bắt buộc và nâng cao cho XenForo 2.3
RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions \
      gd \
      mysqli \
      opcache \
      zip \
      intl \
      gmp \
      bcmath \
      exif \
      imagick \
      redis
# Sử dụng cấu hình production mẫu
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Copy cấu hình tối ưu đè lên
COPY php.ini $PHP_INI_DIR/conf.d/xenforo.ini
WORKDIR /var/www/html

2.4 File app/php.ini (Tối ưu hóa tài nguyên PHP)​

INI:
[PHP]
memory_limit = 256M
post_max_size = 100M
upload_max_filesize = 100M
max_execution_time = 300
max_input_vars = 5000
date.timezone = Asia/Ho_Chi_Minh
[opcache]
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 2
opcache.fast_shutdown = 1

2.5 File web/Caddyfile (Máy chủ Web Caddy)​

Mã:
{$DOMAIN} {
    root * /var/www/html
    encode gzip zstd
    # Quy tắc bảo mật: Không cho phép truy cập trực tiếp các file/thư mục nhạy cảm
    @forbidden {
        path /src/*
        path /internal_data/*
        path /install/data/*
        path /install/templates/*
        path /*.json
        path /*.md
        path /*.lock
        path /*.yml
        path /*.xml
    }
    respond @forbidden "Access Denied" 403
    # Tự động tìm index.php hoặc chuyển hướng Clean URL về index.php
    try_files {path} {path}/index.php /index.php
    # Chuyển tiếp toàn bộ file PHP sang PHP-FPM container
    @php path *.php
    reverse_proxy @php app:9000 {
        transport fastcgi {
            split .php
        }
    }
    # Đọc trực tiếp các file tĩnh (ảnh, css, js)
    file_server
    # Cấu hình các Header bảo mật khuyến nghị
    header {
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
    # Nhật ký truy cập
    log {
        output file /var/log/caddy/access.log {
            roll_size 10mb
            roll_keep 7
        }
    }
}

2.6 File db/my.cnf (Cấu hình tối ưu MariaDB)​

INI:
[mysqld]
max_connections = 150
max_allowed_packet = 64M
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4

PHẦN 3: Trỏ Tên Miền & Cấu Hướng Hosts File​

Tùy vào việc bạn muốn đưa trang web lên chạy thực tế (Production) hay chỉ muốn chạy thử nghiệm cục bộ (Local Testing):

3.1 Dùng Tên Miền Thật (Chạy Thực Tế)​

  1. Trỏ bản ghi A của tên miền bạn về IP của VPS (ví dụ: 103.1.239.239).
  2. Sửa .env: DOMAIN=forum.domain.com.
  3. Chạy docker compose up -d. Caddy sẽ tự liên hệ Let's Encrypt để xin cấp SSL miễn phí và chuyển toàn bộ truy cập từ http sang https.

3.2 Dùng Tên Miền Ảo để Test cục bộ bằng file hosts​

Nếu chưa có tên miền thật và muốn test qua file hosts:
  1. Sửa .env trên VPS: DOMAIN=http://forum.test *(Bắt buộc dùng http:// để Caddy không xin SSL thất bại dẫn đến lỗi).*
  2. Khởi động lại Docker trên VPS: docker compose up -d.
  3. Mở file hosts trên máy tính cá nhân của bạn (đường dẫn: C:\Windows\System32\drivers\etc\hosts) bằng quyền Administrator và thêm dòng:
    Mã:
    103.1.239.239 forum.test
  4. Truy cập trang qua liên kết: từ trình duyệt của máy bạn.

PHẦN 4: Upload Mã Nguồn XenForo & Phân Quyền​

4.1 Upload mã nguồn​

  1. Bạn tải XenForo về máy cá nhân và giải nén ra.
  2. Sao chép toàn bộ các file bên trong thư mục upload/ của XenForo vào thư mục src/ trên VPS của bạn (Bạn có thể dùng phần mềm như FileZilla hoặc WinSCP để upload qua giao thức SFTP).

4.2 Phân quyền thư mục trên Linux VPS (Rất quan trọng)​

Chạy lệnh phân quyền trên terminal của VPS để cho phép Caddy đọc file và PHP-FPM được ghi dữ liệu:
Bash:
# Phân quyền đọc cho Caddy
find src -type d -exec chmod 755 {} +
find src -type f -exec chmod 644 {} +
# Tạo 2 thư mục ghi dữ liệu của XenForo
mkdir -p src/data src/internal_data
# Cấp quyền ghi tối đa (777) cho XenForo hoạt động không bị lỗi
sudo chmod -R 777 src/data src/internal_data

PHẦN 5: Chạy Trình Cài Đặt XenForo Web​

  1. Truy cập vào trang web của bạn qua trình duyệt (ví dụ: https://forum.domain.com/install/ hoặc http://forum.test/install/).
  2. Nhập các thông tin kết nối Database như sau:
    • MySQL server: db *(Phải điền là db chứ không được dùng localhost hoặc 127.0.0.1)*
    • MySQL port: 3306
    • MySQL username: usr_mx_dbadmin
    • MySQL password: Mật khẩu tương ứng cấu hình trong .env (Xf_83d_UserSecurePass_7tWp)
    • Database name: db_mx_prod_forum
  3. Tiến hành các bước tiếp theo để hoàn thành quá trình cài đặt tài khoản Admin của diễn đàn.

PHẦN 6: Kích Hoạt Cache Redis & Quản Lý Session​

Sau khi cài đặt xong XenForo, mở file src/src/config.php trên VPS và thêm đoạn code sau vào cuối file để kích hoạt Redis tăng tốc độ tải trang lên gấp nhiều lần:
PHP:
// Cấu hình Redis làm Cache Provider (Lưu trữ bộ nhớ đệm)
$config['cache']['enabled'] = true;
$config['cache']['provider'] = 'Redis';
$config['cache']['config'] = [
    'host' => 'redis',
    'port' => 6379,
    'password' => 'Rd_49x_RedisSecurePass_9yLr', // Khớp với REDIS_PASSWORD trong .env
    'database' => 0
];
// Cấu hình lưu Session của người dùng vào Redis (Giảm tải cho Database)
$config['session']['cacheLimiter'] = 'public';
$config['session']['provider'] = 'Redis';
$config['session']['config'] = [
    'host' => 'redis',
    'port' => 6379,
    'password' => 'Rd_49x_RedisSecurePass_9yLr',
    'database' => 1
];

PHẦN 7: Quản Trị Database & Import File Lớn (1GB+)​

7.1 Sử dụng phpMyAdmin quản lý Database​

Dịch vụ phpMyAdmin chạy trực tiếp tại cổng 8080 của VPS (đường dẫn: http://IP_CỦA_VPS:8080).
  1. Truy cập trình duyệt và mở trang: http://IP_CỦA_VPS:8080 (ví dụ: http://103.1.239.239:8080).
  2. Đăng nhập bằng tài khoản:
    • Username: root (hoặc usr_mx_dbadmin)
    • Password: Mật khẩu tương ứng cấu hình trong .env (K3p8_9xF2_RootSecurePass_zQ1m hoặc Xf_83d_UserSecurePass_7tWp).
  3. Dịch vụ đã được thiết lập giới hạn tải lên 1.5 GB, bộ nhớ RAM xử lý 2 GB và thời gian chạy tối đa 1 giờ, cho phép import file lớn qua giao diện web.

7.2 Cách Import file Database cực lớn (>500MB) bằng CLI (Khuyên dùng)​

Nếu file database quá nặng, import qua web dễ bị lỗi đứt kết nối mạng giữa chừng. Sử dụng CLI là giải pháp cực kỳ nhanh (mất khoảng vài chục giây) và an toàn tuyệt đối:
  1. Upload file database của bạn (ví dụ tên là backup.sql hoặc backup.sql.gz) vào thư mục backups/ trong dự án trên VPS.
  2. Chạy lệnh dưới đây để nạp dữ liệu:
Bash:
# Trường hợp 1: File định dạng .sql thông thường
docker compose exec -T db mysql -u root -pK3p8_9xF2_RootSecurePass_zQ1m db_mx_prod_forum < ./backups/backup.sql
# Trường hợp 2: File nén định dạng .sql.gz (Giải nén và nạp trực tiếp)
gunzip < ./backups/backup.sql.gz | docker compose exec -T db mysql -u root -pK3p8_9xF2_RootSecurePass_zQ1m db_mx_prod_forum

PHẦN 8: Sao Lưu & Khôi Phục Cơ Sở Dữ Liệu (Backup & Restore)​

8.1 Cơ chế sao lưu tự động (Daily Auto Backup)​

Dịch vụ db-backup chạy ngầm sẽ tự động chụp dữ liệu cơ sở dữ liệu mỗi ngày một lần theo thời gian quy định tại BACKUP_CRON trong .env.
  • File sao lưu sẽ được lưu tại thư mục backups/ trên VPS với định dạng tên: backup_YYYYMMDD_HHMMSS.sql.gz (file nén dung lượng rất nhỏ).
  • Hệ thống tự động xóa các file sao lưu cũ hơn số ngày quy định trong BACKUP_RETAIN_DAYS để tránh đầy dung lượng ổ đĩa.

8.2 Lệnh sao lưu thủ công (Manual Backup)​

Nếu chuẩn bị thực hiện nâng cấp XenForo hoặc cài đặt Add-on mới, bạn nên sao lưu ngay lập tức bằng lệnh sau:
Bash:
docker compose exec db-backup /backup.sh

8.3 Lệnh khôi phục dữ liệu nhanh (Restore)​

Để khôi phục database từ file backup tự động:
Bash:
gunzip < ./backups/tên_file_cần_restore.sql.gz | docker compose exec -T db mysql -u root -pK3p8_9xF2_RootSecurePass_zQ1m db_mx_prod_forum

PHẦN 9: Hướng Dẫn Đổi Mật Khẩu Database Đang Chạy​

Trong trường hợp bạn cần đổi mật khẩu database sau một thời gian chạy:

Bước 9.1: Chạy lệnh SQL đổi mật khẩu bên trong Container Database​

Bash:
# Thay đổi mật khẩu Root:
docker compose exec -T db mysql -u root -pK3p8_9xF2_RootSecurePass_zQ1m -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'mật_khẩu_root_mới'; ALTER USER 'root'@'%' IDENTIFIED BY 'mật_khẩu_root_mới'; FLUSH PRIVILEGES;"
# Thay đổi mật khẩu user 'usr_mx_dbadmin':
docker compose exec -T db mysql -u root -p[mật_khẩu_root_mới] -e "ALTER USER 'usr_mx_dbadmin'@'%' IDENTIFIED BY 'mật_khẩu_user_mới'; FLUSH PRIVILEGES;"

Bước 9.2: Cập nhật lại file .env​

Mở file .env và thay đổi mật khẩu tương ứng để tránh dịch vụ backup và phpMyAdmin bị mất kết nối:
Mã:
DB_ROOT_PASSWORD=mật_khẩu_root_mới
DB_PASSWORD=mật_khẩu_user_mới

Bước 9.3: Sửa mật khẩu mới trong XenForo​

Mở file src/src/config.php và cập nhật dòng cấu hình mật khẩu của XenForo để diễn đàn tiếp tục hoạt động bình thường:
PHP:
$config['db']['password'] = 'mật_khẩu_user_mới';

Bước 9.4: Khởi động lại container​

Bash:
docker compose up -d
 
Bài viết chỉ thể hiện quan điểm cá nhân của tác giả và mang tính tham khảo. Chúng tôi không chịu trách nhiệm cho bất kỳ rủi ro nào phát sinh từ việc sử dụng thông tin trong bài viết.
Back
Top