Hướng dẫn cài đặt WordPress bằng Docker Compose dưới đây sẽ giúp bạn triển khai website WordPress hoàn chỉnh với Nginx, WordPress và MySQL chạy trong ba container riêng biệt, thay vì cài rời từng thành phần dễ gây xung đột và khó bảo trì. Đây là cách làm chuẩn theo tài liệu chính thức […]
Hướng dẫn cài đặt WordPress bằng Docker Compose dưới đây sẽ giúp bạn triển khai website WordPress hoàn chỉnh với Nginx, WordPress và MySQL chạy trong ba container riêng biệt, thay vì cài rời từng thành phần dễ gây xung đột và khó bảo trì. Đây là cách làm chuẩn theo tài liệu chính thức của DigitalOcean, giúp môi trường website luôn đồng nhất, dễ nhân bản giữa các máy chủ. Bạn chỉ cần chuẩn bị một máy chủ sẵn sàng như ThueVPSGiaRe.vn và làm theo đúng thứ tự từng bước bên dưới.
Vì sao nên cài đặt WordPress bằng Docker Compose?
Docker Compose là công cụ cho phép bạn định nghĩa và vận hành nhiều container cùng lúc thông qua một file YAML duy nhất. Khi áp dụng vào WordPress, toàn bộ ứng dụng và cơ sở dữ liệu sẽ được mô tả trong file docker-compose.yml, rồi khởi động chỉ bằng một lệnh — không cần cài rời từng thành phần lên hệ điều hành.
Cài đặt WordPress bằng Docker Compose cho phép bạn triển khai toàn bộ ứng dụng — web server Nginx, WordPress và database MySQL — thành ba container riêng biệt, khởi động chỉ bằng một lệnh duy nhất. Môi trường như vậy luôn đồng nhất giữa các lần triển khai, dễ sao chép sang máy chủ khác và không xung đột thư viện cài rời trên hệ điều hành.
Bài viết bám sát hướng dẫn chính thức của DigitalOcean: WordPress được tải từ image chính thức trên Docker Hub, chạy kèm Nginx làm web server nhận request và MySQL 8.0 làm cơ sở dữ liệu. Ba container này giao tiếp với nhau qua một mạng bridge riêng, đồng thời dùng volume để lưu file mã nguồn, cấu hình Nginx và dữ liệu database.
Nếu bạn mới làm quen với nền tảng này, nên đọc qua bài giới thiệu về công nghệ container hóa của Docker để nắm các khái niệm image, container, volume trước khi bắt đầu.
- webserver: chạy image nginx:1.15.12-alpine, lắng nghe cổng 80 và 443, nhận request rồi chuyển phần PHP về container WordPress.
- wordpress: chạy image wordpress:5.1.1-fpm-alpine — WordPress vận hành với php-fpm, quản lý mã nguồn và giao diện website.
- db: chạy image mysql:8.0.19, lưu trữ toàn bộ bài viết, trang, người dùng của website.
Chuẩn bị gì trước khi cài đặt WordPress bằng Docker Compose?
Để quá trình cài đặt suôn sẻ, bạn cần đáp ứng đầy đủ các điều kiện mà tài liệu gốc yêu cầu trước khi gõ lệnh đầu tiên:
-
- Hệ điều hành máy chủ: Máy chủ Linux (khuyến nghị Ubuntu 22.04 LTS trở lên) đã kích hoạt quyền quản trị
sudovà có địa chỉ IP công khai trên hạ tầng VPS tối ưu cho WordPress. - Docker Engine & Docker Compose: Máy chủ đã hoàn tất thiết lập kiến trúc container Docker kèm theo phiên bản Compose mới nhất. Nếu chưa có, bạn có thể xem lại hướng dẫn cài đặt Docker Compose trên Ubuntu để cập nhật tiện ích chuẩn.
- Tên miền và bản ghi DNS: Một tên miền chính thức (ví dụ:
your_domain.com) đã hoàn thành thao tác trỏ domain về địa chỉ IP máy chủ với 2 bản ghi Type A:your_domain.comvàwww.your_domain.com. - Tường lửa máy chủ: Đã thực hiện mở các cổng kết nối mạng 80 và 443 để sẵn sàng tiếp nhận lưu lượng web truy cập và xác thực SSL từ máy chủ Let’s Encrypt.
- Hệ điều hành máy chủ: Máy chủ Linux (khuyến nghị Ubuntu 22.04 LTS trở lên) đã kích hoạt quyền quản trị
Lưu ý: toàn bộ thao tác đều thực hiện qua terminal SSH trong thư mục dự án. Trong bài, các giá trị như example.com, your_root_password, your_wordpress_database_user, your_wordpress_database_password chỉ là placeholder — hãy thay bằng tên miền và mật khẩu thật của bạn.
Bước 1 — Tạo file cấu hình web server Nginx
Ở bước đầu tiên, bạn sẽ tạo thư mục dự án và file nginx.conf — nơi định nghĩa cách web server Nginx phục vụ website WordPress. Đây là phần quan trọng vì Nginx đóng vai trò nhận request, còn PHP được xử lý bởi container WordPress qua FastCGI.
Trước tiên, tạo thư mục dự án wordpress trong thư mục home và di chuyển vào đó:
mkdir wordpress cd wordpress
Tiếp theo, tạo thư mục con nginx-conf để chứa file cấu hình Nginx:
mkdir nginx-conf
Tạo và mở file nginx.conf bằng nano:
nano nginx-conf/nginx.conf
Thêm vào file nội dung sau. Tài liệu gốc sử dụng cấu hình gồm ba khối chính — user, events và http — trong đó khối http chứa một server block cho website. Thay thế server_name example.com www.example.com bằng tên miền của bạn.
user nginx;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
index index.php index.html index.htm;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
access_log off;
log_not_found off;
expires max;
}
location = /robots.txt {
access_log off;
log_not_found off;
expires max;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
}
Giải thích các dòng quan trọng để bạn hiểu rõ cấu hình vừa tạo:
- listen 80; listen [::]:80; — Nginx lắng nghe request cổng 80 trên cả IPv4 và IPv6.
- server_name example.com www.example.com; — thay bằng tên miền thật của bạn, Nginx sẽ dùng khối server này cho request đến tên miền đó.
- root /var/www/html; — thư mục chứa mã nguồn WordPress, sẽ được mount từ volume wordpress ở bước sau.
- location / — chỉ thị try_files $uri $uri/ /index.php?$query_string; chuyển mọi request không khớp file sang index.php, giúp WordPress xử lý permalink đúng cách.
- location ~ \.php$ — xử lý file PHP: fastcgi_pass wordpress:9000 chuyển request tới container wordpress chạy php-fpm, còn các tham số SCRIPT_FILENAME và PATH_INFO bảo đảm đường dẫn script chính xác.
- location ~ /\.ht — deny all; chặn truy cập các file ẩn như .htaccess, vốn không có tác dụng với Nginx.
- Các location cho favicon.ico, robots.txt và file tĩnh (css|gif|ico|jpeg|jpg|js|png) — bật cache với expires max; và tắt log, giúp giảm tải cho server.
Mẹo: file docker-compose.yml ở bước sau cũng đã thiết lập sẵn vị trí mount chứng chỉ SSL (volume certbot-etc) và mở cổng 443, để bạn có thể nâng cấp lên HTTPS khi sẵn sàng.
Bước 2 — Tạo file .env truyền biến môi trường cho ứng dụng
File .env chứa các thông tin nhạy cảm như mật khẩu database, giúp bạn không phải ghi trực tiếp những giá trị này vào file docker-compose.yml. Trong thư mục dự án wordpress đang mở, tạo file .env bằng lệnh:
nano .env
Thêm ba biến sau, thay giá trị bằng mật khẩu và tên user thật của bạn:
MYSQL_ROOT_PASSWORD=your_root_password MYSQL_USER=your_wordpress_database_user MYSQL_PASSWORD=your_wordpress_database_password
Ý nghĩa từng biến theo tài liệu gốc:
- MYSQL_ROOT_PASSWORD: mật khẩu tài khoản root của MySQL, container db sẽ dùng giá trị này khi khởi tạo.
- MYSQL_USER và MYSQL_PASSWORD: tên user và mật khẩu mà WordPress dùng để kết nối database.
- Cơ chế hoạt động: file .env sẽ được nạp vào container qua chỉ thị env_file trong docker-compose.yml ở bước 3, nên cả container db và wordpress đều dùng chung nguồn thông tin kết nối database.
Lưu ý bảo mật: vì chứa thông tin nhạy cảm, tài liệu gốc khuyến nghị không đưa file .env vào hệ thống version control — nếu dùng Git, hãy thêm .env vào file .gitignore.
Bước 3 — Định nghĩa môi trường web server bằng Docker Compose
Đây là bước cốt lõi của toàn bộ hướng dẫn: tạo file docker-compose.yml khai báo ba dịch vụ webserver, wordpress và db, cùng các volume và network dùng chung. Toàn bộ kiến trúc website của bạn sẽ nằm gọn trong một file duy nhất. Tạo và mở file bằng lệnh:
nano docker-compose.yml
Bước 3 — Định nghĩa môi trường web server bằng Docker Compose
Đây là bước cốt lõi: file docker-compose.yml sẽ khai báo toàn bộ dịch vụ — Nginx, WordPress, MySQL và Certbot — cùng các volume lưu dữ liệu và mạng nội bộ. Từ thời điểm này, toàn bộ kiến trúc website nằm gọn trong một file. Tạo file bằng nano:
nano docker-compose.yml
Thêm vào file nội dung sau. Lưu ý khối dịch vụ certbot đang được comment lại — chúng ta sẽ bỏ comment ở bước 5 khi cần lấy chứng chỉ:
version: '3.3' services: #certbot: # image: certbot/certbot # container_name: certbot # volumes: # - certbot-etc:/etc/letsencrypt # - certbot-var:/var/lib/letsencrypt # - wordpress:/var/www/html # depends_on: # - webserver # command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com webserver: image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt depends_on: - wordpress networks: - app-network wordpress: image: wordpress:5.1.1-fpm-alpine container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - wordpress:/var/www/html networks: - app-network depends_on: - db db: image: mysql:8.0.19 container_name: db restart: unless-stopped env_file: .env command: '--default-authentication-plugin=mysql_native_password' volumes: - dbdata:/var/lib/mysql networks: - app-network volumes: certbot-etc: certbot-var: wordpress: dbdata: networks: app-network: driver: bridge
Giải thích ý nghĩa từng khối để bạn hiểu rõ cấu hình vừa tạo:
Khối dịch vụ certbot (đang được comment)
- image: certbot/certbot — container dùng để lấy chứng chỉ SSL từ Let’s Encrypt.
- command: certonly — chỉ yêu cầu cấp chứng chỉ, không tự sửa cấu hình web server.
- –webroot –webroot-path=/var/www/html — xác thực qua thư mục webroot, nơi volume wordpress được mount để Nginx phục vụ file xác thực.
- –email, –agree-tos, –no-eff-email — email đăng ký và đồng ý điều khoản dịch vụ.
- –force-renewal — yêu cầu cấp lại chứng chỉ mỗi lần service này chạy; đây là lý do cần comment lại khối này sau khi lấy chứng chỉ xong.
- -d example.com -d www.example.com — các tên miền được đưa vào chứng chỉ; hãy thay bằng tên miền thật của bạn.
Khối dịch vụ webserver
- image: nginx:1.15.12-alpine — bản Nginx gọn nhẹ, nhận toàn bộ request HTTP/HTTPS của website.
- ports “80:80” và “443:443” — mở cả cổng HTTP và HTTPS cho máy chủ.
- volumes — volume wordpress mount vào /var/www/html (thư mục gốc chứa mã nguồn), thư mục ./nginx-conf mount vào /etc/nginx/conf.d để Nginx dùng cấu hình tạo ở bước 1, và volume certbot-etc mount vào /etc/letsencrypt để Nginx đọc được chứng chỉ khi bật HTTPS.
- restart: unless-stopped — container tự khởi động lại nếu gặp sự cố, trừ khi bạn chủ động dừng.
Khối dịch vụ wordpress
- image: wordpress:5.1.1-fpm-alpine — WordPress chạy với php-fpm, không kèm web server Apache nên file nhẹ hơn.
- env_file: .env — nạp các biến đã tạo ở bước 2 vào container.
- environment — WORDPRESS_DB_HOST=db:3306 trỏ tới container database qua tên service db; WORDPRESS_DB_USER và WORDPRESS_DB_PASSWORD lấy giá trị từ biến $MYSQL_USER, $MYSQL_PASSWORD trong file .env; WORDPRESS_DB_NAME đặt tên database là wordpress.
- volumes — dùng chung volume wordpress tại /var/www/html, giúp Nginx và php-fpm cùng thao tác trên một bộ file.
- depends_on: db — bảo đảm container db được tạo trước container wordpress.
Khối dịch vụ db
- image: mysql:8.0.19 — hệ quản trị cơ sở dữ liệu MySQL phiên bản 8.0, nơi lưu toàn bộ bài viết, trang và người dùng.
- command: ‘–default-authentication-plugin=mysql_native_password’ — buộc MySQL 8 dùng cơ chế xác thực mysql_native_password để tương thích khi PHP kết nối.
- volumes: dbdata:/var/lib/mysql — dữ liệu database được lưu vào volume dbdata, không mất khi container khởi động lại.
Khối volumes và networks
- certbot-etc, certbot-var, wordpress, dbdata — các volume do Docker quản lý: chứng chỉ SSL, thư mục làm việc của Certbot, mã nguồn WordPress và dữ liệu MySQL.
- app-network với driver: bridge — mạng bridge riêng cho phép các container gọi nhau qua tên service thay vì địa chỉ IP.
Tóm tắt nhanh vai trò từng dịch vụ trong file:
| Dịch vụ | Image | Cổng | Vai trò |
|---|---|---|---|
| webserver | nginx:1.15.12-alpine | 80, 443 | Nhận request, phục vụ file tĩnh, chuyển PHP về container WordPress |
| wordpress | wordpress:5.1.1-fpm-alpine | 9000 (nội bộ) | Chạy WordPress với php-fpm |
| db | mysql:8.0.19 | 3306 (nội bộ) | Lưu trữ database, dữ liệu nằm trong volume dbdata |
| certbot | certbot/certbot | — | Cấp và gia hạn chứng chỉ Let’s Encrypt (bật ở bước 5) |
Bước 4 — Build môi trường và truy cập các container
Khi file docker-compose.yml đã hoàn thiện, một lệnh duy nhất sẽ tạo network, tạo volume, kéo image và khởi động các container theo đúng thứ tự phụ thuộc đã khai báo.
Tại thư mục dự án, chạy lệnh khởi động ở chế độ nền:
docker-compose up -d
Kết quả mẫu bạn sẽ thấy:
Creating network "wordpress_app-network" with driver "bridge" Creating volume "wordpress_certbot-etc" with default driver Creating volume "wordpress_certbot-var" with default driver Creating volume "wordpress_dbdata" with default driver Creating volume "wordpress_wordpress" with default driver Creating db ... done Creating wordpress ... done Creating webserver ... done
Lần chạy đầu tiên, Docker sẽ tải các image Nginx, WordPress và MySQL về từ Docker Hub — tốc độ phụ thuộc băng thông máy chủ và việc bạn đã tải sẵn image này hay chưa. Kiểm tra trạng thái các container:
docker-compose ps
Khi khởi động đúng, db, wordpress và webserver có trạng thái Up, còn certbot có thể trả về Exit 0 sau khi hoàn thành nhiệm vụ.
Nếu trạng thái không đúng, kiểm tra log của service:
docker-compose logs service_name
Sau khi xác nhận các request xác thực hoạt động, kiểm tra chứng chỉ đã được mount vào Nginx:
docker-compose exec webserver ls -la /etc/letsencrypt/live
Nếu cấp chứng chỉ thành công, thư mục tên miền sẽ xuất hiện trong output.
Trong giai đoạn kiểm thử, service Certbot dùng cờ --staging. Khi đã xác nhận quy trình hoạt động, mở lại file Compose:
nano docker-compose.yml
Thay --staging bằng --force-renewal trong command của Certbot:
certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
Sau đó khởi tạo lại container Certbot để áp dụng cấu hình.
Để chuẩn bị firewall cho website HTTPS, bạn có thể tham khảo thêm cách mở các cổng HTTP và HTTPS trên UFW.
7. Bước 5: Cập nhật cấu hình Service và Web Server
Tiếp theo, cấu hình Nginx để hỗ trợ HTTPS. Trước tiên tạm dừng web server:
docker-compose stop webserver
Tải các tham số TLS được Certbot khuyến nghị:
curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf
Các tham số được Certbot cung cấp sẽ được lưu vào file options-ssl-nginx.conf bên trong thư mục nginx-conf. Sau đó, tiến hành xóa file cấu hình Nginx hiện tại:
rm nginx-conf/nginx.conf
Tiếp theo, tạo lại file nginx.conf mới:
nano nginx-conf/nginx.conf
Thêm cấu hình dưới đây để chuyển hướng các request từ HTTP sang HTTPS, đồng thời thiết lập các header bảo mật, giao thức HTTPS và đường dẫn đến chứng chỉ SSL. Hãy thay your_domain bằng tên miền thực tế bạn đã chuẩn bị:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
Trong cấu hình HTTP, server block đầu tiên thiết lập thư mục .well-known/acme-challenge làm webroot để Certbot có thể thực hiện các request phục vụ quá trình gia hạn chứng chỉ. Block này đồng thời sử dụng chỉ thị rewrite để chuyển hướng request HTTP sang phiên bản HTTPS.
Server block HTTPS chịu trách nhiệm tiếp nhận kết nối ssl và http2 thông qua cổng 443. Phần cấu hình này cũng khai báo vị trí của chứng chỉ SSL, khóa SSL và file nginx-conf/options-ssl-nginx.conf, nơi chứa các tham số bảo mật được Certbot khuyến nghị.
Bên cạnh đó, HTTPS server block còn thiết lập một số security header gồm X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Content-Security-Policy và X-XSS-Protection. Các header này có thể hỗ trợ cải thiện mức đánh giá bảo mật trên những công cụ kiểm tra server như SSL Labs hoặc Security Headers.
Header HTTP Strict Transport Security (HSTS) hiện được để ở trạng thái comment mặc định. Chỉ nên kích hoạt header này sau khi đã hiểu rõ cơ chế hoạt động cũng như những ảnh hưởng liên quan đến tùy chọn preload.
HTTPS block cũng khai báo các chỉ thị root và index. Những location block khác đã được đề cập trong bước 1 của quá trình cấu hình. Sau khi hoàn tất, lưu và đóng file để áp dụng nội dung mới.
Trước khi khởi động lại container, cần bổ sung ánh xạ cổng 443 cho service webserver. Mở file docker-compose.yml bằng lệnh:
nano docker-compose.yml
Trong phần cấu hình của service webserver, thêm mapping cho cổng 443 như sau:
... webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network
Sau khi chỉnh sửa, kiểm tra lại toàn bộ nội dung của file docker-compose.yml:
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress
volumes:
- dbdata:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- app-network
wordpress:
depends_on:
- db
image: wordpress:5.1.1-fpm-alpine
container_name: wordpress
restart: unless-stopped
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
networks:
- app-network
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-network
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
Lưu lại file docker-compose.yml sau khi hoàn tất cập nhật. Tiếp theo, khởi tạo lại riêng service webserver bằng lệnh:
docker-compose up -d --force-recreate --no-deps webserver
Sau đó, kiểm tra trạng thái của toàn bộ service bằng:
docker-compose ps
Nếu quá trình triển khai diễn ra bình thường, kết quả trả về sẽ tương tự như sau:
Output
Name Command State Ports
----------------------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcp
Khi các container đã hoạt động ổn định, bạn có thể chuyển sang giao diện web để tiếp tục và hoàn tất quá trình thiết lập WordPress.
Hoàn tất cài đặt và những bước tiếp theo
Sau khi cả ba container chạy ổn định, website của bạn đã sẵn sàng để đưa vào sử dụng. Một số việc nên làm tiếp theo theo đúng tinh thần tài liệu gốc:
- Bật HTTPS cho website: cổng 443 đã được mở và volume certbot-etc đã được mount sẵn trong docker-compose.yml — bạn chỉ cần cài đặt SSL Let’s Encrypt bằng Certbot cho Nginx, rồi mới hoàn tất trình cài đặt WordPress qua giao diện web để bảo vệ thông tin đăng nhập quản trị.
- Quản trị môi trường hằng ngày: dùng docker-compose ps để xem trạng thái, docker-compose down để dừng và gỡ container (dữ liệu vẫn nằm an toàn trong các volume), và docker-compose up -d để khởi động lại toàn bộ môi trường bất cứ lúc nào.
- Giữ dữ liệu an toàn: file WordPress nằm trong volume wordpress, database nằm trong volume dbdata — hãy lập kế hoạch sao lưu định kỳ cho hai volume này trước khi đưa website vào vận hành thật.
- Chọn máy chủ phù hợp lâu dài: nếu bạn đang cân nhắc nơi đặt website, bài tổng hợp kinh nghiệm tối ưu VPS cho WordPress của Fast Byte sẽ giúp bạn chọn cấu hình đúng nhu cầu, tránh mua thừa tài nguyên.
Câu hỏi thường gặp khi cài WordPress bằng Docker Compose
Cách này có khó hơn cài WordPress truyền thống không?
Ngược lại — phần khó nhất là lần đầu viết cấu hình Nginx và docker-compose.yml, mà bài viết này đã cung cấp sẵn toàn bộ theo tài liệu gốc. Từ lần triển khai thứ hai, bạn chỉ cần copy thư mục dự án sang máy chủ mới và chạy docker-compose up -d là có ngay một website giống hệt.
Dữ liệu website có mất khi tắt hoặc khởi động lại container không?
Không. Mã nguồn WordPress được lưu trong volume wordpress và database nằm trong volume dbdata, độc lập với vòng đời container. Dữ liệu chỉ mất khi bạn chủ động xóa volume — vì vậy hãy cẩn trọng khi dùng các lệnh xóa volume của Docker.
Vì sao MySQL 8 cần thêm –default-authentication-plugin=mysql_native_password?
Theo tài liệu gốc, MySQL 8 mặc định dùng cơ chế xác thực mới mà nhiều bản PHP chưa hỗ trợ. Tùy chọn này buộc MySQL sử dụng mysql_native_password để WordPress kết nối được ngay mà không gặp lỗi xác thực.
Có cần HTTPS ngay sau khi cài không?
Nên có, đặc biệt trước khi đăng nhập khu vực quản trị. Docker Compose trong bài đã mở sẵn cổng 443 và mount volume certbot-etc cho mục đích này, nên việc bổ sung Let’s Encrypt về sau rất thuận lợi mà không phải sửa lại cấu hình nền tảng.
Kết luận: Một file cấu hình, ba container, website WordPress sẵn sàng
Cài đặt WordPress bằng Docker Compose thực chất chỉ xoay quanh ba file — nginx.conf, .env và docker-compose.yml — rồi kết thúc bằng một lệnh docker-compose up -d. Ba điều quan trọng cần ghi nhớ: chuẩn bị đúng điều kiện nền tảng (Docker, Docker Compose, tên miền đã trỏ), bảo vệ file .env khỏi lộ thông tin, và tận dụng volume để dữ liệu website luôn bền vững qua mọi lần khởi động lại. Khi môi trường đã chạy, đừng quên bổ sung HTTPS và lịch sao lưu trước khi đưa website vào sử dụng thực tế. Nếu bạn cần một máy chủ để thực hành hoặc vận hành lâu dài, một chiếc VPS ổn định với quyền root đầy đủ sẽ là điểm khởi đầu hợp lý nhất.
Cần một VPS giá rẻ để bắt đầu?
Chạy WordPress bằng Docker Compose không đòi hỏi cấu hình khủng ở giai đoạn đầu — chọn gói vừa đủ nhu cầu, có quyền root để cài Docker và dễ quản trị riêng.
Nội dung bài viết chỉ mang tính tham khảo, được tổng hợp từ hướng dẫn chính thức của DigitalOcean và các lệnh, cấu hình có thể thay đổi theo phiên bản Docker, Docker Compose, hệ điều hành cũng như môi trường thực tế của bạn. Trước khi áp dụng cho website đang vận hành, người đọc nên kiểm thử trên môi trường thử nghiệm, sao lưu dữ liệu và tự đánh giá rủi ro liên quan đến bảo mật, hiệu năng cũng như chi phí vận hành.



