WordPress là một hệ quản trị nội dung (CMS) mã nguồn mở hoàn toàn miễn phí, được xây dựng trên nền tảng cơ sở dữ liệu MySQL và ngôn ngữ lập trình PHP. Nhờ hệ thống plugin phong phú và kho giao diện (template) đa dạng, hầu hết các tác vụ quản trị website đều có thể thực hiện dễ dàng qua giao diện web. Đây cũng là lý do tại sao WordPress luôn là lựa chọn hàng đầu khi xây dựng các loại trang web, từ blog cá nhân, trang giới thiệu sản phẩm cho đến các hệ thống thương mại điện tử (eCommerce) quy mô.
Thông thường, việc vận hành WordPress đòi hỏi bạn phải cài đặt thủ công một bộ công cụ LAMP (Linux, Apache, MySQL, PHP) hoặc LEMP (Linux, Nginx, MySQL, PHP), điều này khá tốn thời gian và dễ phát sinh lỗi cấu hình. Tuy nhiên, bằng cách sử dụng các công cụ hiện đại như Docker và Docker Compose, bạn có thể tinh giản toàn bộ quá trình thiết lập môi trường này. Thay vì cài đặt từng thành phần riêng lẻ, chúng ta sử dụng các image (hình ảnh đóng gói sẵn thư viện, tệp cấu hình và biến môi trường) để chạy trong các container (các tiến trình độc lập hoạt động trên cùng một hệ điều hành máy chủ). Thêm vào đó, Docker Compose sẽ giúp bạn điều phối nhiều container — ví dụ như container ứng dụng và container cơ sở dữ liệu — để chúng giao tiếp trực tiếp với nhau một cách an toàn.
Trong bài viết này, InterData sẽ hướng dẫn bạn cách xây dựng một hệ thống WordPress đa container. Các container của bạn sẽ bao gồm cơ sở dữ liệu MySQL, máy chủ web Nginx và chính mã nguồn WordPress. Ngoài ra, chúng ta cũng sẽ bảo mật hệ thống bằng cách cài đặt chứng chỉ TLS/SSL miễn phí từ Let’s Encrypt thông qua công cụ Certbot, đồng thời thiết lập một tác vụ tự động (cron job) để gia hạn chứng chỉ trước khi hết hạn.

Các Điểm Chính Của Bài Viết:
- Docker Compose tối ưu hóa quy trình triển khai: Loại bỏ việc cài đặt thủ công bộ công cụ LAMP/LEMP phức tạp.
- Mô hình 4 dịch vụ độc lập phối hợp chặt chẽ: Gồm cơ sở dữ liệu MySQL, ứng dụng WordPress (sử dụng PHP-FPM), máy chủ web Nginx và Certbot quản lý chứng chỉ SSL.
- Bảo mật thông tin đăng nhập: Các thông tin nhạy cảm như mật khẩu root MySQL, tài khoản/mật khẩu cơ sở dữ liệu được lưu trữ an toàn trong tệp
.envvà được loại trừ khỏi hệ thống kiểm soát phiên bản (như Git) bằng tệp.gitignorevà.dockerignore. - Sử dụng chứng chỉ SSL Let’s Encrypt miễn phí: Sử dụng cơ chế kiểm thực tên miền thông qua plugin webroot của Certbot, bắt đầu với chứng chỉ thử nghiệm (staging) trước khi cấp chứng chỉ chính thức (production).
- Đảm bảo tính toàn vẹn dữ liệu qua Docker Volumes: Sử dụng các volume tĩnh (
dbdata,wordpress,certbot-etc) để lưu trữ dữ liệu trên ổ đĩa vật lý của máy chủ, giúp dữ liệu không bị mất ngay cả khi container bị khởi động lại hoặc xóa bỏ. - Cấu hình Nginx tối ưu cho WordPress: Thiết lập xử lý PHP qua FastCGI, lưu bộ nhớ đệm (caching) cho tài nguyên tĩnh, áp dụng các tiêu chuẩn bảo mật (X-Frame-Options, Content-Security-Policy) và tự động chuyển hướng HTTP sang HTTPS.
- Giao tiếp nội bộ an toàn: Tất cả các container kết nối chung qua một mạng cầu nội bộ tự định nghĩa (
app-network), chỉ mở cổng công khai 80 và 443 ra môi trường ngoài. - Tự động gia hạn SSL không gây gián đoạn: Sử dụng một tập lệnh shell kết hợp cron job để chạy lệnh
certbot renew, sau đó yêu cầu Nginx tải lại cấu hình (reload) một cách mượt mà.
Yêu Cầu Chuẩn Bị
Để thực hiện thành công hướng dẫn này, quý khách cần chuẩn bị:
- Một máy chủ sử dụng hệ điều hành Ubuntu phiên bản mới (khuyến khích các phiên bản LTS được hỗ trợ lâu dài). Nếu quý khách chưa có máy chủ hoặc đang tìm kiếm một giải pháp lưu trữ mạnh mẽ, hãy tham khảo ngay dịch vụ Thuê VPS giá rẻ của InterData. Các gói VPS tại InterData được tối ưu hóa toàn diện về hiệu năng phần cứng, trang bị ổ cứng NVMe U.2 siêu tốc và cung cấp địa chỉ IP tĩnh riêng biệt, cực kỳ phù hợp để triển khai các ứng dụng Docker.
- Docker đã được cài đặt trên máy chủ Ubuntu.
- Docker Compose đã được cài đặt trên máy chủ.
- Một tên miền (domain) đã đăng ký. Trong bài viết này, chúng tôi sẽ sử dụng mẫu là
your_domain(quý khách cần thay thế bằng tên miền thực tế của mình). - Hai bản ghi DNS (A record) đã trỏ về địa chỉ IP công khai của máy chủ VPS:
- Bản ghi A với tên miền gốc (
your_domain) trỏ về IP máy chủ. - Bản ghi A với tiền tố
www(www.your_domain) trỏ về IP máy chủ.
- Bản ghi A với tên miền gốc (
Khi mọi điều kiện chuẩn bị đã hoàn tất, chúng ta có thể bắt đầu bước đầu tiên.
Các Bước Triển Khai WordPress Với Docker Compose
- Định Cấu Hình Cho Máy Chủ Web Nginx
- Định Nghĩa Các Biến Môi Trường (.env)
- Xây Dựng File Docker Compose
- Lấy Chứng Chỉ SSL Let’s Encrypt
- Cập Nhật Cấu Hình Nginx Và File Compose Cho SSL
- Hoàn Tất Cài Đặt WordPress Trên Giao Diện Web
- Thiết Lập Tự Động Gia Hạn SSL
Bước 1 — Định Cấu Hình Cho Máy Chủ Web Nginx
Trước khi kích hoạt các container, công việc đầu tiên cần làm là thiết lập tệp cấu hình cho máy chủ web Nginx. Tệp này sẽ chứa các chỉ thị định tuyến riêng cho WordPress, đồng thời mở một lối dẫn để Certbot có thể tương tác và xác thực tên miền khi gửi yêu cầu cấp chứng chỉ SSL.
Đầu tiên, hãy tạo một thư mục chứa dự án. Chúng tôi đặt tên thư mục này là wordpress:
mkdir wordpress
cd wordpress
Tiếp theo, tạo thư mục để lưu trữ tệp cấu hình của Nginx:
mkdir nginx-conf
Mở một tệp mới có tên nginx.conf bằng công cụ soạn thảo văn bản nano:
nano nginx-conf/nginx.conf
Quý khách hãy sao chép và dán đoạn mã cấu hình dưới đây vào tệp. Lưu ý thay thế tất cả các giá trị your_domain bằng tên miền chính thức của quý khách:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
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;
}
}
Giải thích các thành phần cấu hình chính:
- Chỉ thị (Directives):
listen: Thiết lập Nginx lắng nghe ở cổng80nhằm đáp ứng yêu cầu xác thực qua HTTP của plugin webroot thuộc Certbot. Ở giai đoạn này, chúng ta chưa định nghĩa cổng443vì chưa có chứng chỉ SSL thực tế.server_name: Khai báo tên miền hệ thống sẽ đón nhận các yêu cầu truy cập gửi tới.index: Thứ tự ưu tiên các tệp tin đóng vai trò là trang chủ của hệ thống. Ở đây chúng tôi ưu tiên đặtindex.phplên trướcindex.html.root: Đường dẫn thư mục gốc chứa mã nguồn trên máy chủ. Giá trị/var/www/htmllà thư mục đích mặc định mà Docker image WordPress sử dụng để chứa mã nguồn.
- Các khối định tuyến (Location Blocks):
location ~ /.well-known/acme-challenge: Đây là nơi tiếp nhận các yêu cầu từ Let’s Encrypt để kiểm tra xem tên miền của quý khách có thực sự trỏ đúng về địa chỉ IP của VPS hay không.location /: Sử dụng chỉ thịtry_filesđể kiểm tra sự tồn tại của tệp tin hay thư mục được yêu cầu. Nếu không tìm thấy, hệ thống sẽ tự động chuyển tiếp yêu cầu đến tệpindex.phpkèm theo các tham số gốc thay vì hiển thị lỗi 404.location ~ \.php$: Tiếp nhận và xử lý các yêu cầu chạy tệp tin PHP, chuyển giao cho tiến trìnhphp-fpmhoạt động tại cổng9000bên trong containerwordpress.location ~ /\.ht: Ngăn chặn tuyệt đối việc truy cập và tải xuống các tệp tin cấu hình nhạy cảm như.htaccess.- Khối xử lý hình ảnh và tài nguyên tĩnh giúp tắt việc ghi nhật ký (log) không cần thiết và thiết lập thời gian lưu bộ nhớ đệm (cache) dài hạn nhằm tối ưu hóa tốc độ tải trang.
Nhấn tổ hợp phím CTRL+X, chọn Y, rồi gõ ENTER để lưu lại và đóng tệp cấu hình.
Bước 2 — Định Nghĩa Các Biến Môi Trường (.env)
Hệ quản trị cơ sở dữ liệu và ứng dụng WordPress cần các thông tin kết nối để có thể khởi chạy và lưu trữ dữ liệu lâu dài. Để tránh việc để lộ các thông tin đăng nhập quan trọng (như mật khẩu quản trị database) khi chia sẻ dự án lên các kho lưu trữ trực tuyến (như GitHub), cách an toàn nhất là sử dụng một tệp chứa các biến môi trường riêng biệt có tên .env.
Tại thư mục làm việc chính (~/wordpress), hãy tạo tệp .env:
nano .env
Thêm các khóa và giá trị mật khẩu của quý khách vào tệp này (quý khách hãy thay đổi các giá trị mật khẩu mẫu dưới đây bằng các chuỗi bảo mật phức tạp hơn):
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password
Lưu và đóng tệp.
Để đảm bảo tệp .env không bị đẩy lên Git hoặc Docker container một cách ngoài ý muốn, hãy cấu hình các tệp loại trừ. Đầu tiên, khởi tạo thư mục này như một kho lưu trữ Git (nếu quý khách có ý định quản lý phiên bản mã nguồn):
git init
Tạo và mở tệp .gitignore:
nano .gitignore
Thêm dòng sau vào tệp tin:
.env
Lưu và đóng tệp. Tương tự, chúng ta cũng tạo tệp .dockerignore:
nano .dockerignore
Định nghĩa các tệp và thư mục cần bỏ qua khi xây dựng Docker image:
.env
.git
docker-compose.yml
.dockerignore
Lưu lại và đóng tệp. Bước chuẩn bị biến môi trường đã hoàn thành.
Bước 3 — Xây Dựng File Docker Compose
Tệp docker-compose.yml có nhiệm vụ mô tả chi tiết cách thức vận hành cũng như mối liên kết giữa các container trong hệ thống ứng dụng của quý khách.
Tạo và mở tệp docker-compose.yml:
nano docker-compose.yml
Dán toàn bộ nội dung cấu hình hệ thống dưới đây vào tệp:
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"
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 --staging -d your_domain -d www.your_domain
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
Chi tiết các thành phần chính trong tệp cấu hình:
- Dịch vụ
db(MySQL Database): Sử dụng phiên bản ổn địnhmysql:8.0. Chỉ thịvolumesgắn kết thư mục lưu trữ dữ liệu của MySQL với một volume trên ổ đĩa vật lý có têndbdatađể bảo toàn cơ sở dữ liệu. Lệnh khởi chạy được thiết lập tùy chọn--default-authentication-plugin=mysql_native_passwordnhằm đảm bảo tính tương thích với cơ chế đăng nhập cũ của PHP-FPM trong WordPress. - Dịch vụ
wordpress: Container này phụ thuộc trực tiếp vào tiến trình cơ sở dữ liệu (depends_on: db). Chúng tôi lựa chọn phiên bản nhỏ gọn xây dựng trên nền Alpine Linux (wordpress:5.1.1-fpm-alpine). Biến môi trường kết nối cơ sở dữ liệu sẽ tự động lấy từ tệp.env. Thư mục gốc chứa mã nguồn của WordPress được ánh xạ vào volume tĩnhwordpress. - Dịch vụ
webserver(Nginx): Lắng nghe và mở cổng80kết nối trực tiếp ra bên ngoài VPS. Nó chia sẻ chung mã nguồn qua volume tĩnhwordpressvà lấy cấu hình Nginx cục bộ từ thư mụcnginx-confthông qua cơ chế bind mount. - Dịch vụ
certbot: Đây là dịch vụ chạy một lần rồi tắt, có nhiệm vụ gửi yêu cầu xác thực tên miền tới Let’s Encrypt. Tham số--staginggiúp bạn gửi yêu cầu thử nghiệm nhằm kiểm tra cấu hình hệ thống mà không lo bị chặn hoặc dính giới hạn yêu cầu (rate limit) từ máy chủ Let’s Encrypt. Quý khách nhớ đổisammy@your_domainsang email của mình vàyour_domainsang tên miền thật. - Volumes & Networks: Định nghĩa các volume dùng chung cho hệ thống và thiết lập mạng cầu nội bộ
app-networkgiúp các container nhận diện và truyền tải gói tin qua lại một cách an toàn mà không cần công khai toàn bộ các cổng ra ngoài internet.
Lưu và đóng tệp sau khi đã chỉnh sửa chính xác các giá trị.
Bước 4 — Lấy Chứng Chỉ SSL Let’s Encrypt
Bây giờ là lúc chúng ta tiến hành khởi động hệ thống container để bắt đầu yêu cầu chứng chỉ SSL thử nghiệm.
Sử dụng lệnh sau để khởi chạy các container dưới dạng chạy ngầm (-d):
docker-compose up -d
Hệ thống sẽ tải các image cần thiết và khởi chạy các dịch vụ:
OutputCreating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... done
Kiểm tra trạng thái hoạt động của các tiến trình bằng lệnh:
docker-compose ps
Nếu thành công, trạng thái của db, wordpress, và webserver sẽ hiển thị là Up, riêng container certbot sẽ hiển thị trạng thái kết thúc thành công là Exit 0:
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:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcp
(Mẹo bảo trì: Nếu có dịch vụ nào gặp lỗi không thể chuyển sang trạng thái Up, quý khách có thể kiểm tra nhật ký lỗi bằng lệnh docker-compose logs <tên_dịch_vụ> để khắc phục).
Bây giờ hãy xác nhận xem chứng chỉ thử nghiệm đã được lưu vào thư mục chia sẻ của Nginx hay chưa bằng lệnh:
docker-compose exec webserver ls -la /etc/letsencrypt/live
Nếu thấy có thư mục chứa tên miền của quý khách xuất hiện, quá trình kiểm tra thử nghiệm đã hoàn tất thành công:
Outputtotal 16
drwx------ 3 root root 4096 May 10 15:45 .
drwxr-xr-x 9 root root 4096 May 10 15:45 ..
-rw-r--r-- 1 root root 740 May 10 15:45 README
drwxr-xr-x 2 root root 4096 May 10 15:45 your_domain
Khi cấu hình đã chạy tốt, chúng ta sẽ tiến hành xin cấp chứng chỉ SSL chính thức (production). Mở lại tệp docker-compose.yml:
nano docker-compose.yml
Tìm đến phần khai báo của dịch vụ certbot, sửa đổi câu lệnh thực thi bằng cách xóa bỏ tham số --staging và thêm vào tham số --force-renewal để bắt buộc đăng ký mới đè lên chứng chỉ cũ:
...
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
...
Chạy lệnh dưới đây để yêu cầu Docker Compose tái tạo riêng container certbot và bỏ qua việc kiểm tra các dịch vụ khác (--no-deps):
docker-compose up --force-recreate --no-deps certbot
Nhật ký màn hình sẽ hiện thông báo chúc mừng chứng chỉ SSL chính thức của quý khách đã được tạo lập và lưu trữ thành công trên ổ đĩa máy chủ VPS:
OutputRecreating certbot ... done
Attaching to certbot
...
certbot | IMPORTANT NOTES:
certbot | - Congratulations! Your certificate and chain have been saved at:
certbot | /etc/letsencrypt/live/your_domain/fullchain.pem
...
certbot exited with code 0
Bước 5 — Cập Nhật Cấu Hình Nginx Và File Compose Cho SSL
Có được chứng chỉ SSL, chúng ta cần cấu hình lại Nginx để kích hoạt giao thức HTTPS bảo mật tại cổng 443 và thiết lập chuyển hướng tự động toàn bộ truy cập không bảo mật (HTTP cổng 80) sang HTTPS.
Đầu tiên, tạm thời dừng hoạt động của container Nginx:
docker-compose stop webserver
Tiếp theo, tải tệp cấu hình bảo mật SSL tiêu chuẩn do Certbot khuyến nghị bằng lệnh curl sau:
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
Xóa bỏ tệp cấu hình Nginx cũ:
rm nginx-conf/nginx.conf
Tạo một tệp cấu hình mới:
nano nginx-conf/nginx.conf
Sao chép toàn bộ mã cấu hình hỗ trợ SSL hoàn chỉnh dưới đây. Chú ý thay đổi your_domain thành tên miền thực tế:
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;
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;
}
}
Lưu và đóng tệp cấu hình Nginx.
Bây giờ chúng ta cần ánh xạ cổng 443 từ container Nginx ra ngoài máy chủ trong tệp docker-compose.yml để người dùng có thể truy cập qua HTTPS.
Mở tệp docker-compose.yml:
nano docker-compose.yml
Tìm đến phần dịch vụ webserver và cập nhật danh sách cổng (ports) 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
...
Lưu tệp docker-compose.yml và thoát. Khởi chạy lại dịch vụ webserver để áp dụng cấu hình mới:
docker-compose up -d --force-recreate --no-deps webserver
Xem trạng thái hoạt động của hệ thống bằng lệnh docker-compose ps. Lúc này, máy chủ web của quý khách đã mở cả hai cổng truy cập tiêu chuẩn:
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
Bước 6 — Hoàn Tất Cài Đặt WordPress Trên Giao Diện Web
Tại trình duyệt web cá nhân, hãy truy cập vào địa chỉ tên miền của quý khách:
https://your_domain
Quý khách sẽ thấy giao diện cài đặt chào mừng mặc định của hệ thống WordPress được hiển thị an toàn qua giao thức bảo mật HTTPS:
- Lựa chọn ngôn ngữ: Chọn ngôn ngữ phù hợp (ví dụ: Tiếng Việt hoặc English) rồi bấm Tiếp tục (Continue).
- Khai báo thông tin quản trị: Nhập tiêu đề cho website, đặt tên tài khoản quản trị (tránh dùng tên mặc định “admin” để tăng cường độ bảo mật) và điền mật khẩu đăng nhập cá nhân bảo mật cao. Điền chính xác địa chỉ thư điện tử (email) của quý khách.
- Bấm nút Cài đặt WordPress (Install WordPress) ở góc dưới cùng màn hình.
Hệ thống sẽ chuyển hướng quý khách sang trang đăng nhập quản trị. Sau khi đăng nhập thành công, bảng điều khiển quản trị WordPress (Dashboard) sẽ hiển thị đầy đủ tính năng.
Bước 7 — Thiết Lập Tự Động Gia Hạn SSL
Chứng chỉ cấp bởi tổ chức Let’s Encrypt chỉ có giá trị hiệu lực trong vòng 90 ngày. Để đảm bảo website hoạt động ổn định và liên tục mà không lo chứng chỉ hết hạn, chúng ta sẽ thiết lập quy trình tự động kiểm tra và gia hạn.
Tạo một tập lệnh shell mới có tên ssl_renew.sh:
nano ssl_renew.sh
Dán nội dung tập lệnh sau vào tệp tin. Lưu ý thay thế đường dẫn /home/sammy/wordpress/ thành đường dẫn thư mục dự án thực tế trên máy chủ của quý khách (ví dụ /home/ten_user/wordpress/):
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"
cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
Nguyên lý hoạt động của đoạn mã lệnh trên:
- Di chuyển vào thư mục làm việc chứa tệp compose của WordPress.
- Khởi chạy container
certbottạm thời để chạy lệnh kiểm tra gia hạn SSL với tùy chọn thử nghiệm--dry-run. Nếu phát hiện chứng chỉ sắp hết hạn và gia hạn thành công, nó sẽ gửi tín hiệuSIGHUPđể yêu cầu Nginx tải lại cấu hình mới mà không làm gián đoạn các kết nối hiện tại của khách hàng truy cập website. - Chạy lệnh dọn dẹp hệ thống
docker system prune -afđể giải phóng dung lượng ổ cứng bị chiếm dụng bởi các container tạm thời và các bản build không còn sử dụng.
Lưu tệp tin và cấp quyền thực thi cho tập lệnh:
chmod +x ssl_renew.sh
Tiếp theo, chúng ta đăng ký tập lệnh này với trình lập lịch tác vụ tự động cron của hệ thống máy chủ dưới quyền tài khoản root:
sudo crontab -e
Nếu đây là lần đầu truy cập cấu hình cron, quý khách hãy chọn số ứng với trình soạn thảo văn bản dễ dùng nhất (ví dụ chọn 1 cho /bin/nano).
Ở dòng cuối cùng của tệp, thêm dòng kiểm tra thử nghiệm (chạy tự động mỗi 5 phút một lần):
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
Lưu tệp cấu hình cron lại và thoát ra ngoài. Sau khoảng 5 phút, quý khách kiểm tra tệp tin nhật ký ghi nhận để xem tác vụ tự động có chạy bình thường và không xảy ra lỗi hay không:
tail -f /var/log/cron.log
Khi nhìn thấy dòng chữ xác nhận giả lập thành công dưới đây, tập lệnh của quý khách đã hoạt động trơn tru:
Output** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
Nhấn CTRL+C để thoát màn hình xem nhật ký.
Giờ đây, khi quy trình đã được kiểm tra thành công, hãy mở lại bảng cấu hình crontab -e và cập nhật lại chu kỳ chạy thực tế (ví dụ chạy vào lúc 12:00 trưa mỗi ngày thay vì mỗi 5 phút):
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
Đồng thời, mở lại tệp tin ssl_renew.sh để loại bỏ cờ thử nghiệm --dry-run nhằm tiến hành thực hiện gia hạn thật khi đến hạn:
nano ssl_renew.sh
Cập nhật dòng lệnh chạy certbot:
...
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
...
Lưu tệp tin và hoàn tất. Toàn bộ hệ thống WordPress Docker Compose và cơ chế bảo mật tự động của quý khách đã được vận hành hoàn chỉnh và an toàn.
Các Câu Hỏi Thường Gặp (FAQs)
1. Tại sao tôi nên sử dụng Docker Compose để triển khai WordPress?
Việc sử dụng Docker Compose giúp đơn giản hóa toàn bộ quá trình cài đặt. Thay vì phải mất hàng giờ để cài đặt và cấu hình thủ công từng thành phần của bộ công cụ LEMP hay LAMP trên hệ điều hành máy chủ, bạn chỉ cần định nghĩa tất cả các dịch vụ (Database, WordPress, Web Server Nginx) trong một tệp duy nhất là docker-compose.yml để kích hoạt toàn bộ hệ thống chỉ bằng một dòng lệnh. Phương pháp này cũng giúp đồng nhất môi trường hoạt động và dễ dàng sao chép hoặc di chuyển dự án sang các hệ thống máy chủ khác.
2. Máy chủ web Nginx kết nối và truyền tin đến WordPress như thế nào?
Container Nginx (webserver) và container WordPress kết nối nội bộ qua một mạng cầu ảo được đặt tên là app-network. Trong tệp cấu hình nginx.conf, chúng ta cấu hình chỉ thị fastcgi_pass wordpress:9000;. Nginx sẽ phân giải tên dịch vụ wordpress thành địa chỉ IP nội bộ của container tương ứng trong mạng ảo Docker và chuyển tiếp các yêu cầu xử lý mã nguồn PHP đến đó một cách an toàn.
3. Phương thức quản lý thông tin đăng nhập nhạy cảm (như mật khẩu cơ sở dữ liệu) được thực hiện thế nào để đảm bảo tính an toàn?
Toàn bộ thông tin nhạy cảm được tách biệt hoàn toàn khỏi cấu hình mã nguồn và tệp compose bằng cách lưu trữ tập trung tại tệp .env. Cả hai container db và wordpress sẽ đọc trực tiếp giá trị này thông qua chỉ thị env_file: .env. Bằng việc bổ sung tệp .env vào các danh sách từ chối theo dõi .gitignore và .dockerignore, thông tin đăng nhập của quý khách sẽ không bị lộ ra ngoài internet hoặc tích hợp nhầm vào Docker image.
4. Quy trình đăng ký chứng chỉ SSL được thực thi như thế nào?
Quy trình được thực hiện qua 4 giai đoạn chính:
- Chạy thử nghiệm (Staging): Khởi chạy hệ thống ban đầu với cờ
--stagingcủa Certbot để kiểm thử kết nối định tuyến và tránh dính các hạn chế về số lần yêu cầu từ tổ chức cấp chứng chỉ. - Kiểm tra: Xác thực tệp chứng chỉ thử nghiệm được ghi nhận chính xác tại thư mục
/etc/letsencrypt/livecủa máy chủ web. - Cấu hình chứng chỉ chính thức: Chỉnh sửa cấu hình, loại bỏ tham số
--staging, đồng thời cấu hình thêm tham số--force-renewal. - Nhận chứng chỉ thực tế: Chạy lệnh cập nhật để Certbot thực hiện lấy chứng chỉ bảo mật thực tế để đưa vào sử dụng công khai.
5. Cơ chế tự động gia hạn chứng chỉ SSL hoạt động ra sao?
Chứng chỉ SSL miễn phí được tự động kiểm tra định kỳ thông qua một tập lệnh shell có tên ssl_renew.sh. Khi chạy, tập lệnh sẽ kích hoạt tạm thời container Certbot để kiểm tra hạn dùng của chứng chỉ hiện tại. Nếu chứng chỉ chuẩn bị hết hạn, Certbot tự động gia hạn mới và gửi tín hiệu SIGHUP yêu cầu Nginx tải lại cấu hình để áp dụng chứng chỉ mới mà không làm dừng hoạt động của máy chủ web. Quy trình này được điều phối tự động hàng ngày bằng công cụ lập lịch tác vụ cron trên máy chủ.
6. Nếu tôi tắt hoặc khởi động lại các container, dữ liệu trang web của tôi có bị mất không?
Dữ liệu của quý khách được bảo vệ an toàn nhờ cơ chế Docker Named Volumes (Volume tĩnh được đặt tên). Các thư mục quan trọng như dữ liệu cơ sở dữ liệu (/var/lib/mysql), mã nguồn và ảnh tải lên của WordPress (/var/www/html), cùng các chứng chỉ bảo mật (/etc/letsencrypt) đều được liên kết trực tiếp với ổ đĩa vật lý của máy chủ VPS. Do đó, các hoạt động tắt, bật hoặc nâng cấp container sẽ không gây mất mát dữ liệu của trang web.
7. Tham số cấu hình bổ sung trong phần dịch vụ db có ý nghĩa gì?
Kể từ phiên bản MySQL 8.0, hệ thống sử dụng cơ chế bảo mật xác thực mặc định mới cao hơn. Tuy nhiên, các phiên bản PHP cũ dùng trong WordPress chưa kịp hỗ trợ chuẩn xác thực mới này, dẫn đến lỗi mất kết nối cơ sở dữ liệu. Chỉ thị cấu hình command: '--default-authentication-plugin=mysql_native_password' buộc container MySQL sử dụng phương thức xác thực truyền thống tương thích tốt với mã nguồn PHP của WordPress.
8. Container Nginx lấy tệp chứng chỉ SSL từ container Certbot bằng cách nào?
Cả hai container webserver và certbot cùng gắn kết chung vào một volume tĩnh có tên là certbot-etc trỏ đến thư mục /etc/letsencrypt. Khi Certbot hoàn tất việc xác thực và ghi tệp chứng chỉ mới vào volume này, Nginx có thể ngay lập tức truy cập và đọc các tệp khóa bảo mật tương ứng để phục vụ việc giải mã kết nối HTTPS của người dùng.
Lời Kết
Trong tài liệu hướng dẫn này, chúng ta đã áp dụng thành công công nghệ Docker Compose để xây dựng nhanh chóng một trang web WordPress hoạt động đồng bộ với máy chủ web Nginx trên nền tảng máy chủ Ubuntu. Quý khách cũng đã tự tay bảo mật website của mình bằng chứng chỉ bảo mật cao cấp Let’s Encrypt thông qua công cụ tự động Certbot và lập lịch tự động gia hạn một cách an toàn.
Để tối ưu hóa trải nghiệm tải trang của người dùng và xây dựng hệ thống website lớn mạnh, hoạt động liên tục không gián đoạn, một hạ tầng lưu trữ mạnh mẽ đóng vai trò vô cùng then chốt. Dịch vụ VPS của InterData tự hào mang đến cho quý khách giải pháp máy chủ riêng ảo vượt trội, sở hữu cấu hình phần cứng thế hệ mới, tối ưu hóa riêng cho môi trường chạy Docker, cùng đội ngũ kỹ thuật viên giàu kinh nghiệm hỗ trợ 24/7/365. Hãy liên hệ ngay với InterData để lựa chọn gói VPS phù hợp nhất cho dự án của quý khách!
