Triển khai WordPress bằng Portainer: Nginx, MySQL, SSL đầy đủ
Bạn có VPS. Muốn chạy WordPress ổn định. Không muốn gõ Docker dài. Không muốn sửa Nginx thủ công mỗi lần thêm site. Portainer → quản trị Docker bằng UI. Nginx Proxy Manager → reverse proxy + SSL Let’s Encrypt. MySQL → DB riêng. WordPress → chạy trong container, dễ backup, dễ nâng cấp.
Mô hình này phù hợp blog cá nhân, landing page, site doanh nghiệp nhỏ/vừa. Ưu điểm: tách dịch vụ, dễ di chuyển, dễ rollback, SSL tự động, không đụng quá sâu vào host.
Kiến trúc triển khai
Mô hình:
– Portainer → quản lý Docker qua web. – Nginx Proxy Manager → nhận HTTP/HTTPS từ internet. – WordPress container → chạy PHP/Apache nội bộ. – MySQL container → lưu DB. – Docker network → các container giao tiếp riêng. – Volumes → giữ dữ liệu bền vững.
Luồng req:
User → domain.com → Nginx Proxy Manager → WordPress → MySQL
Cổng public cần mở:
– 80 → HTTP, cấp SSL.
– 443 → HTTPS.
– 9443 → Portainer, nên giới hạn IP nếu có thể.
– 81 → Nginx Proxy Manager UI, nên chặn public sau cấu hình.
Chuẩn bị VPS
Yêu cầu tối thiểu:
– Ubuntu 22.04/24.04. – RAM 1GB chạy được, 2GB+ khuyến nghị. – Docker + Docker Compose plugin. – Domain trỏ A record về IP VPS.
Cài Docker nhanh:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USERĐăng xuất/đăng nhập lại. Kiểm tra:
docker version
docker compose versionTạo thư mục dự án:
mkdir -p ~/stacks/wordpress
cd ~/stacks/wordpressCài Portainer
Portainer giúp tạo stack, xem logs, restart container, chỉnh env, quản lý volumes.
Chạy:
docker volume create portainer_data
docker run -d
--name portainer
--restart=always
-p 9443:9443
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
portainer/portainer-ce:latest
Mở:
https://YOUR_SERVER_IP:9443Tạo admin user. Chọn Docker local environment.
Lưu ý bảo mật:
– Dùng password mạnh.
– Không public Portainer nếu không cần.
– Nên firewall giới hạn IP truy cập 9443.
Tạo Docker network chung
Network chung giúp Nginx Proxy Manager nhìn thấy WordPress container.
Trong terminal:
docker network create proxyNếu làm trong Portainer: Networks → Add network → name: proxy → bridge.
Network này dùng cho:
– Nginx Proxy Manager. – WordPress app.
MySQL có thể nằm cùng network riêng của stack. Nhưng để đơn giản, dùng chung stack network + proxy cho WordPress.
Triển khai Nginx Proxy Manager
Tạo stack trong Portainer: Stacks → Add stack → name: npm.
Dán:
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
- "80:80"
- "81:81"
- "443:443"
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
networks:
- proxy
volumes:
npm_data:
npm_letsencrypt:
networks:
proxy:
external: true
Deploy. Mở:
http://YOUR_SERVER_IP:81Login mặc định:
Email: [email protected]
Password: changemeĐổi ngay email/password.
Cảnh báo: cổng 81 là dashboard quản trị. Sau khi cấu hình xong, nên firewall giới hạn IP hoặc không expose public nếu dùng VPN/tunnel.
Triển khai WordPress + MySQL
Tạo stack mới: Stacks → Add stack → name: wordpress-site1.
Dùng Compose:
services:
db:
image: mysql:8.0
container_name: wp_db_site1
restart: unless-stopped
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: change_this_strong_password
MYSQL_ROOT_PASSWORD: change_this_root_password
volumes:
- db_data:/var/lib/mysql
networks:
- internal
wordpress:
image: wordpress:latest
container_name: wp_app_site1
restart: unless-stopped
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: change_this_strong_password
volumes:
- wp_data:/var/www/html
networks:
- internal
- proxy
volumes:
db_data:
wp_data:
networks:
internal:
proxy:
external: true
Trước deploy, đổi password. Không dùng password mẫu.
Deploy stack. Kiểm tra logs:
– Portainer → Containers → wp_app_site1 → Logs.
– Không lỗi DB connection → ổn.
WordPress chưa public trực tiếp vì không map port. Đúng. Nginx Proxy Manager sẽ route nội bộ.
Trỏ domain
Trong DNS provider:
A @ YOUR_SERVER_IP
A www YOUR_SERVER_IPChờ DNS propagate. Kiểm tra:
dig domain.com +short
dig www.domain.com +shortKết quả phải là IP VPS.
Cấu hình Nginx Proxy Manager
Vào NPM:
Hosts → Proxy Hosts → Add Proxy HostTab Details:
– Domain Names: domain.com, www.domain.com
– Scheme: http
– Forward Hostname/IP: wp_app_site1
– Forward Port: 80
– Cache Assets: bật tùy chọn
– Block Common Exploits: bật
– Websockets Support: thường không cần, bật cũng được
Tab SSL:
– Request a new SSL Certificate – Email: email thật – Agree Let’s Encrypt Terms – Force SSL: bật – HTTP/2 Support: bật – HSTS: chỉ bật khi chắc chắn site luôn HTTPS
Save.
Nếu thành công: truy cập https://domain.com → màn hình cài WordPress.
Nếu lỗi SSL:
– DNS chưa trỏ đúng.
– Port 80/443 bị firewall/cloud firewall chặn.
– Domain đang bật proxy/CDN sai mode.
– Container NPM không chạy.
Cài WordPress ban đầu
Mở:
https://domain.comChọn:
– Ngôn ngữ. – Site title. – Admin username. – Password mạnh. – Email admin.
Không dùng username admin. Sau cài đặt:
– Settings → Permalinks → chọn Post name.
– Settings → General → kiểm tra URL là https://domain.com.
– Cài plugin cần thiết vừa đủ.
Nếu WordPress nhận sai HTTPS, thêm vào wp-config.php. Với Docker volume, có thể exec:
docker exec -it wp_app_site1 bashSửa:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}Thường image WordPress + NPM xử lý ổn. Chỉ sửa khi bị redirect loop hoặc mixed scheme.
Tối ưu cấu hình thực tế
Upload size
Mặc định có thể thấp. Tạo file custom PHP config.
Cách nhanh: mount thêm file uploads.ini.
Tạo thư mục:
mkdir -p ~/stacks/wordpress/php
nano ~/stacks/wordpress/php/uploads.iniNội dung:
file_uploads = On
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300Sửa service WordPress:
volumes:
- wp_data:/var/www/html
- ./php/uploads.ini:/usr/local/etc/php/conf.d/uploads.iniRedeploy stack.
Bộ nhớ
VPS RAM thấp → thêm swap:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabSwap không thay RAM thật, nhưng giúp tránh MySQL chết khi spike.
Cache
Nên dùng:
– Plugin cache: LiteSpeed Cache không tối ưu nếu không dùng LiteSpeed; dùng WP Super Cache, W3 Total Cache, hoặc Cache Enabler. – Object cache: Redis nếu site lớn. – CDN: Cloudflare cho static assets.
Với Nginx Proxy Manager, có thể bật Cache Assets, nhưng cache app-level vẫn cần plugin.
Backup đúng cách
Dữ liệu quan trọng gồm:
– wp_data → code, themes, plugins, uploads.
– db_data → MySQL data.
– DB dump → an toàn hơn backup raw volume.
Backup DB:
docker exec wp_db_site1 mysqldump
-u root
-pchange_this_root_password
wordpress > wordpress.sqlBackup volume:
docker run --rm
-v wordpress-site1_wp_data:/data
-v $(pwd):/backup
alpine tar czf /backup/wp_data.tar.gz -C /data .Khuyến nghị:
– Backup hằng ngày DB. – Backup uploads hằng ngày/tuần tùy tần suất. – Đẩy backup ra ngoài VPS: S3, Backblaze B2, Google Drive, rsync server. – Test restore định kỳ. Backup chưa test → chưa chắc dùng được.
Nâng cấp container an toàn
WordPress app có 2 lớp:
– WordPress core/plugin/theme trong volume. – Container image PHP/Apache.
Cách nâng cấp image:
1. Backup DB + files. 2. Trong Portainer → Stack → Pull latest image/redeploy. 3. Kiểm tra logs. 4. Mở site, test login, post, upload.
MySQL major upgrade cần cẩn trọng. Không nhảy tùy tiện từ 5.7 → 8.0 hoặc 8.0 → 8.4 nếu chưa đọc migration note. Với site production, pin version:
image: mysql:8.0Không dùng latest cho DB production.
Bảo mật cần làm
– Admin WordPress: password mạnh + 2FA. – Portainer/NPM UI: giới hạn IP bằng firewall. – VPS: chỉ mở port cần thiết. – SSH: key-based login, tắt password login nếu quen vận hành. – WordPress: xóa theme/plugin không dùng. – Cập nhật plugin đều. – Không cấp quyền ghi lung tung trên host. – Không đưa DB port ra public. – Không commit password vào repo public.
UFW mẫu:
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow from YOUR_IP to any port 9443
sudo ufw allow from YOUR_IP to any port 81
sudo ufw enableLỗi thường gặp
Error establishing a database connection
Nguyên nhân:
– Sai WORDPRESS_DB_PASSWORD.
– DB chưa ready.
– Sai hostname DB.
Fix:
– WORDPRESS_DB_HOST: db:3306
– Kiểm tra logs MySQL.
– Không đổi env DB sau khi volume đã tạo mà không hiểu tác động.
502 Bad Gateway
Nguyên nhân:
– NPM không thấy WordPress container. – Sai Forward Hostname. – WordPress chưa chạy.
Fix:
– WordPress phải join network proxy.
– Forward Hostname dùng wp_app_site1.
– Check logs.
SSL không cấp được
Nguyên nhân:
– DNS sai. – Port 80 bị chặn. – AAAA record trỏ sai IPv6. – Cloudflare SSL mode gây lỗi.
Fix:
– Xóa AAAA nếu không dùng IPv6. – Mở port 80/443. – Tạm tắt proxy Cloudflare khi cấp cert.
Kết luận
Portainer + Nginx Proxy Manager + MySQL + WordPress là combo gọn, dễ vận hành, đủ mạnh cho nhiều website production nhỏ/vừa. Portainer giúp quản trị trực quan. NPM xử lý reverse proxy + SSL sạch. Docker volumes giữ dữ liệu độc lập. Compose stack giúp tái tạo nhanh.
Điểm mấu chốt: không expose DB, backup đều, giới hạn UI quản trị, pin version DB, kiểm tra logs khi lỗi. Làm đúng từ đầu → triển khai WordPress mới chỉ mất vài phút, thêm domain mới cũng rất nhanh.
Bình luận (0)
Chưa có bình luận. Hãy là người đầu tiên!