Fast Byte - Thuê VPS Giá Rẻ
Hướng dẫn chung

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 […]

Ảnh đại diện Thanh Lam NguyễnThanh Lam Nguyễn21 phút đọ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:

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.

Thuê VPS giá rẻ

CPU Intel Gold, SSD NVMe U.2, giá từ 50K/tháng

Máy chủ chuyên biệt chạy Docker/ WordPress mượt mà, ổn định

Dịch vụ VPS tại Fast Byte cung cấp tài nguyên phần cứng độc lập, ổ cứng SSD NVMe tốc độ cao và băng thông rộng lớn, giúp hệ thống container WordPress, Nginx và MySQL hoạt động bền bỉ, phản hồi tức thì với chi phí cực kỳ tiết kiệm.

Tham khảo VPS giá rẻ

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.

Thuê VPS giá rẻ

CPU Intel Gold, SSD NVMe U.2, giá từ 50K/tháng

Chạy WordPress bằng Docker cần một máy chủ đủ khỏe

Ba container chạy song song trong cùng một máy chủ khiến RAM và ổ cứng là hai yếu tố bạn nên ưu tiên: MySQL cần bộ nhớ để xử lý truy vấn, còn SSD NVMe giúp database và file WordPress phản hồi nhanh. VPS giá rẻ của Fast Byte cho quyền root đầy đủ, sẵn sàng cài Docker và làm thực hành theo bài hướng dẫn này.

Tham khảo VPS giá rẻ

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.

Xem bảng giá VPS

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.

Chia sẻ: Facebook LinkedIn
Quay lại trang blog

Bài viết liên quan

Cài Đặt PostgreSQL Trên Ubuntu
Hướng dẫn chung

Hướng Dẫn Cài Đặt PostgreSQL Trên Ubuntu Từ Số 0 Đến A-Z Cho Người Mới

Hướng dẫn cài đặt và sử dụng PostgreSQL trên Ubuntu dưới đây dành cho người mới đang cần dựng một hệ quản trị cơ sở dữ liệu mạnh mẽ trên máy chủ nhưng chưa biết bắt đầu từ đâu. Bạn sẽ lần lượt cài PostgreSQL bằng apt, quản lý role và database, rồi tạo bảng […]

Thanh Lam Nguyễn
Đọc bài viết