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.
*(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ọ).*
Cấu trúc thư mục mong muốn:
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ềnsudo, 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
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ế)
- Trỏ bản ghi A của tên miền bạn về IP của VPS (ví dụ:
103.1.239.239). - Sửa
.env:DOMAIN=forum.domain.com. - 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ừhttpsanghttps.
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 filehosts:- Sửa
.envtrê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).* - Khởi động lại Docker trên VPS:
docker compose up -d. - 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 - 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
- Bạn tải XenForo về máy cá nhân và giải nén ra.
- 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
- Truy cập vào trang web của bạn qua trình duyệt (ví dụ:
https://forum.domain.com/install/hoặchttp://forum.test/install/). - 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
- MySQL server:
- 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ổng8080 của VPS (đường dẫn: http://IP_CỦA_VPS:8080).- Truy cập trình duyệt và mở trang: http://IP_CỦA_VPS:8080 (ví dụ: http://103.1.239.239:8080).
- Đăng nhập bằng tài khoản:
- Username:
root(hoặcusr_mx_dbadmin) - Password: Mật khẩu tương ứng cấu hình trong
.env(K3p8_9xF2_RootSecurePass_zQ1mhoặcXf_83d_UserSecurePass_7tWp).
- Username:
- 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:- Upload file database của bạn (ví dụ tên là
backup.sqlhoặcbackup.sql.gz) vào thư mục backups/ trong dự án trên VPS. - 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.
Bài viết liên quan


