Email Doanh NghiệpSSLFirewall Anti DDoS

NỘI DUNG

Banner blog lễ 30.4 và 1.5

Hướng dẫn cách cài đặt WordPress bằng Docker Compose

Cao Lê Viết Tiến

Đã kiểm duyệt nội dung

Ngày đăng:25/09/2025
Lượt xem

Đánh giá

5/5 - (122 bình chọn)
công nghệ Vietnix Speed Optimizer

Docker Compose là công cụ giúp bạn dễ dàng triển khai và quản lý nhiều container cùng lúc, điển hình như WordPress, cơ sở dữ liệu và Nginx. Giải pháp này mang lại lợi ích lớn về tính linh hoạt, khả năng tái sử dụng cấu hình và tiết kiệm thời gian thiết lập môi trường. Trong bài viết này, mình sẽ hướng dẫn chi tiết cách cài đặt WordPress bằng Docker Compose để bạn nhanh chóng sở hữu một website hoàn chỉnh và ổn định.

Những điểm chính

  1. Giới thiệu tổng quan về WordPress: Hiểu rõ WordPress là gì, vai trò của Docker Compose trong việc triển khai và vì sao nên chọn Nginx làm web server.
  2. Chuẩn bị để cài đặt WordPress bằng Docker Compose: Biết được các công cụ, môi trường và file cấu hình cần thiết trước khi bắt đầu.
  3. Các bước cài đặt WordPress bằng Docker Compose: Nắm được toàn bộ quy trình từ thiết lập web server, khai báo biến môi trường, định nghĩa service, tích hợp SSL, cập nhật cấu hình cho đến hoàn tất cài đặt và gia hạn chứng chỉ.
  4. Biết thêm Vietnix – Nhà cung cấp dịch vụ VPS, hosting tốc độ cao.
  5. Câu hỏi thường gặp: Tổng hợp các thắc mắc phổ biến khi triển khai WordPress bằng Docker Compose và cách giải quyết.
những điểm chính

Giới thiệu tổng quan về WordPress

WordPress là một hệ quản trị nội dung (CMS) mã nguồn mở miễn phí, viết bằng PHP và sử dụng cơ sở dữ liệu MySQL. Nhờ hệ thống template và cấu trúc plugin dễ mở rộng, hầu hết tác vụ quản lí của WordPress có thể thực hiện bằng giao diện web. Vì lí do trên, WordPress trở nên nổi tiếng trong lĩnh vực thiết kế các loại website như blog, trang sản phẩm hay các trang thương mại điện tử.

Giới thiệu tổng quan về WordPress
Giới thiệu tổng quan về WordPress

Để sử dụng WordPress, các bạn cần cấu hình LAMP stack (Linux, Apache, MySQL và PHP) hoặc LEMP stack (Linux, Nginx, MySQL và PHP). Do thực hiện thủ công khá tốn thời gian, Vietnix sẽ hướng dẫn các bạn sử dụng Docker và Docker Compose để hỗ trợ cài đặt. Quy trình bao gồm việc thiết lập các thư viện, file cấu hình và biến môi trường bằng Docker image. Những image này sau đó được thực thi độc lập trong các container. Cuối cùng, chúng ta sẽ sử dụng Compose để cấu hình cho các container có khả năng giao tiếp (cơ sở dữ liệu và WordPress).

Các thông tin trong bài viết này sẽ giúp bạn biết cách cài đặt WordPress bằng multi-container (nhiều container): cơ sở dữ liệu MySQL, web server Nginx cũng như bản thân WordPress. Bạn sẽ cần yêu cầu Let’s Encrypt cấp các chứng chỉ TLS/SSL để bảo mật cho tên miền website. Ngoài ra, mình sẽ hướng dẫn các bạn cấu hình cho chứng chỉ có thể tự động gia hạn, đảm bảo trạng thái bảo mật của website luôn được duy trì.

Sau khi đã nắm được cách cài đặt WordPress bằng Docker Compose, bạn sẽ thấy rõ sức mạnh của việc chủ động triển khai và quản lý hệ thống. Tuy nhiên, không phải lúc nào bạn cũng có đủ thời gian và nguồn lực để duy trì server riêng. Đây là lúc các giải pháp WordPress Hosting trở nên cần thiết, giúp bạn vận hành website ổn định, bảo mật và tối ưu hiệu suất mà không phải lo lắng về hạ tầng. Nếu bạn muốn mở rộng quy mô hoặc quản lý nhiều website cùng lúc, các gói web hosting chuyên nghiệp từ Vietnix sẽ là lựa chọn đáng cân nhắc, mang lại sự tiện lợi và hiệu quả lâu dài. Liên hệ ngay!

img sp wphosting 1

TĂNG TỐC TỐI ĐA Với Hosting WORDPRESS

Nâng tầm website WordPress của bạn: Nhanh, ổn định và an toàn hơn

Chuẩn bị để cài đặt WordPress bằng Docker Compose

Trước khi cài đặt, bạn cần đáp ứng các yêu cầu sau:

  • Đăng nhập server Ubuntu 20.04 bằng tài khoản non-root với đặc quyền sudo và kích hoạt tường lửa.
  • Cài đặt Docker.
  • Cài đặt Docker Compose.
  • Đăng ký một tên miền. Trong bài hướng dẫn này, mình sẽ ví dụ tên miền là your_domain.
  • Cấu hình hai DNS record:
    • Một A record với tên miền your_domain trỏ tới địa chỉ IP của server.
    • Một A record với tên miền www.your_domain trỏ tới địa chỉ IP của server.

Sau khi chuẩn bị xong, bạn hãy đến với các bước cài đặt chi tiết dưới đây:

Bước 1: Thiết lập cấu hình Web Server

Để bắt đầu, các bạn cần cấu hình cho Nginx bằng cách thêm một số location block đặc trưng của WordPress vào file cấu hình. Một location block khác cũng được thêm để hỗ trợ tự động gia hạn chứng chỉ cho website. Block này có nhiệm vụ điều hướng các request xác minh của Let’s Encrypt đến Certbot. Đầu tiên, bạn tạo một thư mục dự án để cài đặt WordPress. Bạn có thể tùy ý đặt tên thư mục. Ở đây, thư mục sẽ được đặt tên là wordpress.

$ mkdir wordpress

Bạn mở thư mục vừa tạo bằng lệnh:

$ cd wordpress

Tiếp theo, bạn tạo thư mục chứa file cấu hình:

$ mkdir nginx-conf

Sau khi tạo xong, bạn sử dụng nano hoặc trình editor khác tùy thích để mở file:

$ nano nginx-conf/nginx.conf

Tiếp theo, bạn thêm một server block vào file để thiết lập server_name cũng như thư mục mã nguồn root. Trong đó, một số location block được bổ sung để điều hướng các request của Certbot yêu cầu chứng chỉ, tài nguyên tĩnh và mã nguồn PHP. Bạn dán đoạn code dưới đây vào file, đừng quên thay your_domain bằng tên miền của đã chuẩn bị:

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;
        }
}

Các thông tin trong server block bao gồm:

Các chỉ thị (directive):

    • listen: Mở cổng 80 để plugin webroot của Certbot có thể xử lí các request yêu cầu chứng chỉ. Tạm thời, các bạn chưa bao gồm mở cổng 443. Ở những bước tiếp theo, sau khi tên miền đã được Certbot xác thực, các bạn sẽ bổ sung SSL và cập nhật lại cấu hình cho Nginx.
    • server_name: Chọn server name và server block cho các request. Đừng quên thay your_domain bằng tên miền của các bạn.
    • index: Liệt kê các trang chỉ mục của request. Các bạn có thể thay đổi thứ tự trả về của file tại đây (đặt file index.php trước index.html để Nginx ưu tiên gọi index.php khi request không yêu cầu file cụ thể).
    • root: Chọn thư mục chứa mã nguồn website. Ngoài ra, theo mặc định trong WordPress Dockerfile, /var/www/html còn là một mount point (thư mục chứa các file được mount) khi build image WordPress.

    Location block:

    • location ~ /.well-known/acme-challenge: Cấu hình cách xử lí các request đến thư mục .well-known. Certbot sẽ tạo một file tạm trong thư mục này nhằm đối chiếu DNS tên miền với server của bạn, từ đó sử dụng webroot plugin để cấp chứng chỉ cho tên miền.
    • location /: Chứa chỉ thị try_files giúp xác định các tài nguyên được yêu cầu bởi URI request. Trường hợp không tìm thấy, request và các đối số sẽ được điều hướng đến file index.php của WordPress, thay vì trả về trạng thái mặc định 404 Not Found.
    • location ~ \.php$: Xử lí và ủy quyền các PHP request đến wordpress container. Do Nginx không có trình xử lí PHP, chúng ta sử dụng trình php-fpm được image php:fpm tích hợp sẵn. Vì phụ thuộc image php:fpm, các bạn cần cấu hình bổ sung một số tùy chọn của giao thức FastCGI. Các tùy chọn trên có nhiệm vụ ủy quyền những request PHP cho wordpress, đồng thời hỗ trợ phân tích cú pháp và trả về tài nguyên được các request URI yêu cầu.
    • location ~/\.th: Chứa chỉ thị deny_all, đảm bảo Nginx không phục vụ cho người dùng các file .htaccess.
    • location = /favicon.ico, location = /robots.txt: Không lưu lịch sử các request yêu cầu file /favicon.ico/robots.txt.
    • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: Không lưu lịch sử các request tài nguyên tĩnh. Vì khá tốn kém để phục vụ, ta cần đảm bảo những tài nguyên này dễ lưu vào bộ nhớ đệm cache.

    Các bạn đóng file và lưu lại các tùy chọn vừa thiết lập. Như vậy, mình đã hướng dẫn xong cách để cấu hình Nginx web server. Ở bước tiếp theo sẽ giúp bạn biết cách tạo các biến môi trường mà container WordPress và MySQL sử dụng trong quá trình thực thi.

    Bước 2: Định nghĩa biến môi trường (Environment Variables)

    Khi thực thi, các container WordPress và MySQL sử dụng biến môi trường nhằm đảm bảo khả năng truy cập ứng dụng và tính nhất quán dữ liệu. Những biến môi trường này bao gồm mật khẩu root của MySQL, người dùng và mật khẩu truy cập (thông tin nhạy cảm) cũng như tên và host (thông tin không nhạy cảm) của cơ sở dữ liệu.

    Thay vì thiết lập toàn bộ trong file Docker Compose (file quy định hành động của container), mình sẽ lưu và giới hạn truy cập cho các thông tin nhạy cảm vào file .env. Bằng cách này, bạn có thể ngăn thông tin bị sao chép sang các repository khác và tránh nguy cơ bị lộ dữ liệu. Các bạn đến thư mục dự án và mở file .env bằng lệnh sau:

    $ nano .env

    Mình sẽ lưu vào .env mật khẩu root của MySQL cũng như người dùng và mật khẩu mà WordPress sử dụng để truy cập cơ sở dữ liệu:

    MYSQL_ROOT_PASSWORD=your_root_password
    MYSQL_USER=your_wordpress_database_user
    MYSQL_PASSWORD=your_wordpress_database_password

    Đóng và lưu file để cập nhật các thay đổi. Vì lưu thông tin nhạy cảm, bạn cần thêm .env vào các file .gitignore.dockerignore. Bằng cách này, .env sẽ không được Git và Docker sao chép đến các Git repository cũng như các Docker image. Nếu quản lý version control bằng Git, bạn mở thư mục dự án và gọi lệnh git init để tạo một repository:

    $ git init

    Bạn tạo và mở file .gitignore:

    $ nano .gitignore

    Thêm .env vào file vừa tạo:

    .env

    Đóng và lưu file để cập nhật thay đổi. Để an toàn hơn, bạn nên thêm .env vào .dockerignore, tránh trường hợp .env được sao chép vào các container khi thư mục dự án được sử dụng làm build context.

    Sau đó, bạn mở .dockerignore bằng lệnh:

    $ nano .dockerignore

    Thêm .env vào file:

    .env

    Bạn có thể tiếp tục thêm vào những dòng tiếp theo một số file và thư mục tùy chọn trong quá trình cài đặt:

    .env
    .git
    docker-compose.yml
    .dockerignore

    Đóng và lưu file để lưu lại các thay đổi. Sau khi cấu hình xong cho các thông tin quan trọng, bạn tiến hành định nghĩa các service trong file docker-compose.yml.

    Bước 3: Định nghĩa service với Docker Compose

    docker-compose.yml là file định nghĩa các service cho quá trình cài đặt. Mỗi service sẽ tương ứng và quy định cách hoạt động của một container.

    Compose cho phép các service kết nối qua mạng chia sẻ (shared network) và những không gian lưu trữ liên tục (volume). Vì vậy, bạn có thể định nghĩa nhiều service nếu muốn chạy một ứng dụng multi-container (nhiều container). Trong bài viết này, để hỗ trợ cài đặt WordPress, mình sẽ tạo một số container bao gồm: Cơ sở dữ liệu MySQL, ứng dụng WordPress, web server Nginx và một container Certbot có nhiệm vụ xác thực tên miền.

    Đầu tiên, bạn tạo và mở file docker-compose.yml:

    $ nano docker-compose.yml

    Thêm đoạn code sau để khai báo phiên bản Compose và định nghĩa service db cho cơ sở dữ liệu:

    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

    Cấu hình của service db bao gồm:

    • image: Quy định image được dùng để tạo container. Do image mysql:latest luôn thay đổi, để tránh xung đột, ở đây mình sẽ sử dụng cố định phiên bản image mysql:8.0.
    • container_name: Đặt tên cho container.
    • restart: Chọn cách container tái khởi động. Thông thường, giá trị mặc định của restartno. Tuy nhiên, ở đây sẽ cho phép container tự khởi động lại trừ khi service được dừng bởi người quản trị.
    • env_file: Cho phép bổ sung biến môi trường từ file .env trong build context (thư mục hiện hành).
    • environment: Bổ sung biến môi trường không được định nghĩa trong .env. Các bạn gán wordpress cho biến MYSQL_DATABASE để đặt tên cơ sở dữ liệu. Bạn có thể trực tiếp thêm giá trị này vào file docker-compose.yml vì tên cơ sở dữ liệu không phải là thông tin nhạy cảm.
    • volumes: Mount (sao chép) volume có tên dbdata (named volume) vào thư mục /var/lib/mysql trên container. Đây là thư mục dữ liệu chuẩn của MySQL ở hầu hết các phiên bản.
    • command: Ghi đè các lệnh CMD (CMD instruction) mặc định của image. Ở đây, bạn sẽ thêm một lệnh mới vào tập lệnh tiêu chuẩn trong mysql:8.0 để khởi động server MySQL trên container. Vì image WordPress và PHP không hỗ trợ các phương thức xác thực gần đây của MySQL, bạn cần bổ sung tùy chọn --default-authentication-plugin=mysql_native_password để quy định cơ chế xác minh người dùng (mysql_native_password) cho cơ sở dữ liệu.
    • networks: Thêm service vào mạng app-network được định nghĩa cuối file.

    Tiếp theo, bạn tiến hành cấu hình service wordpress:

    ...
      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

    Trong service này, ngoài đặt tên và thiết lập quy luật tái khởi động như db, bạn cần bổ sung một số tùy chọn đặc trưng dưới đây của wordpress, bao gồm:

    • depends_on: Đảm bảo các container khởi động theo đúng thứ tự phụ thuộc. Vì WordPress sử dụng cơ sở dữ liệu và thông tin người dùng, để ứng dụng hoạt động ổn định, bạn cần cấu hình cho service wordpress khởi động sau service db.
    • image: Tạo container bằng image WordPress 5.1.1-fpm-alpine – một image alpine có nguồn gốc từ dự án Alpine Linux. 5.1.1-fpm-alpine có nhiệm vụ giảm kích thước image tổng thể, đồng thời cung cấp trình php-fpm cần thiết để hỗ trợ Nginx xử lí các request PHP (đề cập ở trên).
    • env_file: Tương tự db, bạn tiếp tục sử dụng file .env để lấy người dùng và mật khẩu truy cập cơ sở dữ liệu.
    • environment: Gán người dùng và mật khẩu từ .env cho 2 biến WORDPRESS_DB_USERWORDPRESS_DB_PASSWORD của image WordPress. WORDPRESS_DB_HOST sẽ truy cập server MySQL trên cổng mặc định 3306 của service db. Tên cơ sở dữ liệu WORDPRESS_DB_NAME được gán bằng tên mà các bạn đặt trong thân service của MySQL trước đó (MYSQL_DATABASE: wordpress).
    • volumes: Mount volume có tên wordpress vào thư mục /var/www/html được tạo bởi image WordPress. Bằng cách này, mã nguồn ứng dụng của các bạn có thể được chia sẻ giữa các container.
    • networks: thêm container wordpress vào mạng app-network.

    Tiếp theo, bạn sẽ tiến hành định nghĩa service Nginx webserver:

    ...
      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

    Bạn đặt tên và cấu hình cho service webserver khởi động sau wordpress, đồng thời tạo container bằng image Nginx 1.15.12-alpine. Các tùy chọn bổ sung của webserver bao gồm:

    • ports: Mở cổng 80, tạo điều kiện để cấu hình trong file nginx.conf ở bước 1 hoạt động.
    • volumes: Định nghĩa nhóm các volume có tên và các bind mount (sao chép liên kết):
      • wordpress:/var/www/html: mount mã nguồn WordPress vào thư mục /var/www/html – thư mục root trong server block Nginx.
      • ./nginx-conf:/etc/nginx/conf.d: Bind mount thư mục cấu hình Nginx từ host vào thư mục tương ứng trong container, đảm bảo tất cả thay đổi trên host đều được cập nhật ở container.
      • certbot-etc:/etc/letsencrypt: Mount các khóa và chứng nhận tên miền Let’s Encrypt liên quan vào thư mục thích hợp trong webserver.

    Bạn cũng thêm container này vào mạng app-network. Sau service webserver, bạn tiến hành định nghĩa cho service certbot, đừng quên thay đổi tên miền và địa chỉ email sử dụng.

    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

    Với service này, bạn sẽ nhờ Compose kéo image certbot/certbot từ Docker Hub để tạo container. Bạn sử dụng những volume có tên để chia sẻ tài nguyên với container Nginx, bao gồm các khóa, chứng nhận tên miền trong thư mục certbot-etc cũng như mã nguồn ứng dụng trong wordpress container.

    Bạn tiếp tục cấu hình depends_on để đảm bảo certbot khởi động sau service webserver. Cuối cùng, bạn thêm một tùy chọn command để bổ sung các subcommand (lệnh con) vào các lệnh mặc định của certbot. Các lệnh con certonly này có nhiệm vụ cấp một chứng chỉ với các tùy chọn:

    • --webroot: Chọn webroot làm thư mục chứa các file xác thực của webroot plugin. Plugin sẽ gọi một HTTP request để chứng minh Certbot có thể lấy tài nguyên định sẵn khi server phản hồi lại tên miền được cung cấp (phương pháp xác thực HTTP-01).
    • --webroot-path: Cho biết đường dẫn đến thư mục webroot.
    • --email: Email tùy chọn cho việc đăng ký và phục hồi.
    • --agree-tos: Chấp thuận các điều khoản trong ACME’s Subcriber Agreement (Thỏa thuận Đăng ký Người dùng ACME).
    • --no-eff-email: Ngăn Certbot chia sẻ email cho EFF (Electronic Frontier Foundation). Tùy chọn này có thể bỏ qua.
    • --staging: Sử dụng môi trường staging của Let’s Encrypt để thử nghiệm yêu cầu chứng chỉ. Tùy chọn này giúp bạn kiểm tra lại thiết lập cấu hình, đồng thời tránh khả năng bị giới hạn request của tên miền.
    • -d: Liệt kê danh sách tên miền sẽ phản hồi các request. Đừng quên sử dụng đúng tên miền các bạn đã chuẩn bị.

    Sau khi certbot được cấu hình, bạn tiếp tục định nghĩa các volume và mạng.

    ...
    volumes:
      certbot-etc:
      wordpress:
      dbdata:
    
    networks:
      app-network:
        driver: bridge

    volumes là khóa top-level dùng để định nghĩa các volume certbot-etc, dbdatawordpress. Khi được tạo, các volume sẽ được lưu trong thư mục /var/lib/docker/volumes/ – quản lý bởi Docker trên filesystem (hệ thống file) của host. Khi có nhu cầu sử dụng, nội dung của các volume sẽ được mount đến các container để chia sẻ dữ liệu và mã nguồn.

    Định nghĩa bridge network (cầu nối mạng) app-network cho phép các container trên cùng một Docker daemon host có thể giao tiếp. Nhờ mở toàn bộ cổng nội bộ nhưng không để lộ các cổng nào ra ngoài, bridge network có khả năng điều phối lưu lượng mạng và hỗ trợ giao tiếp giữa các container, giúp db, wordpresswebserver có thể giao tiếp với nhau trên cùng một host. Để front-end truy cập ứng dụng, bạn chỉ cần mở cổng 80.

    Cuối cùng, bạn có thể xem lại toàn bộ file docker-compose.yml vừa thiết lập như sau:

    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

    Sau đó, bạn đóng file và lưu lại các cấu hình. Như vậy là đã hoàn tất việc định nghĩa các service. Giờ đây, các bạn đã sẵn sàng cho việc khởi động các container và gọi thử các request yêu cầu chứng chỉ cho tên miền.

    Bước 4: Yêu cầu chứng chỉ và chứng nhận SSL

    Bạn sử dụng lệnh docker-compose up để khởi động các container theo thứ tự, đồng thời bổ sung cờ -d để cho phép db, wordpresswebserver chạy nền bằng lệnh:

    $ docker-compose up -d

    Các service được tạo sẽ hiển thị trong Output dưới đây:

    Output
    Creating db ... done
    Creating wordpress ... done
    Creating webserver ... done
    Creating certbot   ... done

    Bạn kiểm tra trạng thái của service bằng lệnh docker-compose ps:

    $ docker-compose ps

    Khi hoàn tất khởi động, các service db, wordpresswebserver sẽ có trạng thái Up, riêng certbot sẽ trả về thông điệp 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

    Trường hợp cột State không hiển thị như trên, các bạn có thể kiểm tra lại service logs bằng lệnh docker-compose logs:

    $ docker-compose logs service_name

    Nếu mọi việc suôn sẻ, bạn gọi lệnh docker-compose exec để kiểm tra các chứng chỉ được mount đến container webserver:

    $ docker-compose exec webserver ls -la /etc/letsencrypt/live

    Các chứng chỉ được cấp thành công sẽ được hiển thị trong Output:

    Output
    total 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

    Sau khi đảm bảo các request xác thực đã hoạt động, các bạn có thể cập nhật lại định nghĩa service certbot và bỏ đi cờ --staging. Bạn mở lại file docker-compose.yml.

    $ nano docker-compose.yml

    Dưới tùy chọn command của service, các bạn thay cờ --staging bằng cờ --force-renewal. Thiết lập này cho phép chúng ta yêu cầu chứng chỉ mới cho một tên miền đã xác thực. Các bạn có thể kiểm tra lại cấu hình certbot sau khi thay đổi.

    ...
      certbot:
        depends_on:
          - webserver
        image: certbot/certbot
        container_name: certbot
        volumes:
          - certbot-etc:/etc/letsencrypt
          - certbot-var:/var/lib/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
    ...

    Các bạn gọi lệnh docker-compose up để khởi tạo lại container certbot. Ngoài ra, vì webserver đã hoạt động, chúng ta sẽ bổ sung cờ --no-deps để ngăn Certbot khởi động service này:

    $ docker-compose up --force-recreate --no-deps certbot

    Output dưới đây cho biết các bạn đã yêu cầu chứng chỉ thành công:

    Output
    Recreating certbot ... done
    Attaching to certbot
    certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
    certbot      | Plugins selected: Authenticator webroot, Installer None
    certbot      | Renewing an existing certificate
    certbot      | Performing the following challenges:
    certbot      | http-01 challenge for your_domain
    certbot      | http-01 challenge for www.your_domain
    certbot      | Using the webroot path /var/www/html for all unmatched domains.
    certbot      | Waiting for verification...
    certbot      | Cleaning up challenges
    certbot      | IMPORTANT NOTES:
    certbot      |  - Congratulations! Your certificate and chain have been saved at:
    certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
    certbot      |    Your key file has been saved at:
    certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
    certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
    certbot      |    version of this certificate in the future, simply run certbot
    certbot      |    again. To non-interactively renew *all* of your certificates, run
    certbot      |    "certbot renew"
    certbot      |  - Your account credentials have been saved in your Certbot
    certbot      |    configuration directory at /etc/letsencrypt. You should make a
    certbot      |    secure backup of this folder now. This configuration directory will
    certbot      |    also contain certificates and private keys obtained by Certbot so
    certbot      |    making regular backups of this folder is ideal.
    certbot      |  - If you like Certbot, please consider supporting our work by:
    certbot      | 
    certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
    certbot      |    Donating to EFF:                    https://eff.org/donate-le
    certbot      | 
    certbot exited with code 0

    Sau khi được cấp chứng chỉ, bạn sẽ tiến hành bổ sung SSL và cập nhật lại cấu hình cho Nginx.

    Bước 5: Cập nhật cấu hình Service và Web Server

    Để cấu hình SSL cho Nginx, các bạn cần bổ sung một số thiết lập, bao gồm: Điều hướng HTTP đến HTTPS, chỉ định thư mục chứa các khóa và chứng chỉ SSL, thêm một vài tham số và header (tiêu đề) cho request. Vì webserver sẽ được khởi tạo lại trong chốc lát, bạn tạm thời dừng service bằng lệnh sau:

    $ docker-compose stop webserver

    Trước khi cập nhật cấu hình, bạn sử dụng curl để lấy danh sách tham số bảo mật khuyên dùng cho Nginx:

    $ 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

    Dòng lệnh trên sẽ lưu các tham số cung cấp bởi Certbot vào file options-ssl-nginx.conf trong thư mục nginx-conf. Tiếp theo, bạn xóa file cấu hình Nginx ban đầu.

    $ rm nginx-conf/nginx.conf

    Bạn tạo lại một phiên bản khác của file:

    $ nano nginx-conf/nginx.conf

    Các bạn thêm đoạn code sau để điều hướng HTTP đến HTTPS, đồng thời bổ sung các header bảo mật, các giao thức cũng như các chứng chỉ SSL. Đừng quên thay your_domain bằng tên miề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;
            }
    }

    Server block HTTP sẽ quy định thư mục .well-known/acme-challenge làm webroot cho các renewal request (yêu cầu gia hạn) từ Certbot, đồng thời hỗ trợ điều hướng HTTP đến thư mục root của HTTPS bằng cách bổ sung một chỉ thị rewrite. Server block HTTPS cho phép lắng nghe sslhttp2 trên cổng 443. Block cũng bao gồm đường dẫn đến các khóa, chứng chỉ SSL và file nginx-conf/options-ssl-nginx.conf – nơi lưu các tham số bảo mật được khuyên dùng của Certbot.

    Ngoài ra, block còn bổ sung một số header bảo mật như: X-Frame-Options, X-Content-Type-Options, Referrer Policy, Content-Security-PolicyX-XSS-Protection. Những header này có thể giúp các bạn đạt A rating trên các trang thử nghiệm server như SSL Labs hoặc Security Headers. Mặc định, header HTTP Strict Transport Security (HSTS) sẽ được comment. Bạn chỉ nên sử dụng header này một khi đã xem xét và nắm rõ được chức năng “preload”.

    Block HTTPS cũng bao gồm các chỉ thị rootindex. Những location block còn lại chúng ta đã được tìm hiểu trong bước 1 của bài. Bạn đóng và lưu file để cập nhật lại cấu hình. Trước khi tái khởi động container, bạn cần bổ sung mapping (ánh xạ) cho cổng 443 vào service webserver. Các bạn mở file docker-compose.yml:

    $ nano docker-compose.yml

    Trong service webserver, bạn thêm mapping của cổng 443:

    ...
      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

    Các bạn kiểm tra lại file docker-compose.yml sau khi chỉnh sửa:

    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

    Đóng và lưu file để cập nhật cấu hình. Bạn tiến hành khởi tạo lại service webserver:

    $ docker-compose up -d --force-recreate --no-deps webserver

    Một lần nữa, bạn gọi lệnh docker-compose ps để kiểm tra các service:

    $ docker-compose ps

    Nếu mọi việc suôn sẻ, bạn sẽ nhận được output dưới đây.

    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

    Giờ đây, khi các container đã hoạt động ổn định, bạn sẽ sử dụng giao diện web để hoàn tất thiết lập cho WordPress.

    Bước 6: Hoàn tất cài đặt bằng giao diện web

    Các bạn truy cập vào tên miền của server. Đừng quên thay đổi your_domain bằng tên miền đã chuẩn bị.

    https://your_domain

    Chọn ngôn ngữ hiển thị:

    Trang tùy chọn ngôn ngữ WordPress
    Trang tùy chọn ngôn ngữ WordPress

    Click chọn Continue, các bạn sẽ được chuyển đến trang thiết lập chính của WordPress. Bạn tiến hành đặt tên cho website và chọn tên đăng nhập. Thay vì “admin”, bạn nên chọn một tên đăng nhập dễ nhớ khác đi kèm một mật khẩu mạnh. Nếu không muốn dùng mật khẩu riêng, các bạn có thể sử dụng mật khẩu tự tạo của WordPress. Cuối cùng, bạn cung cấp địa chỉ email và cho biết bạn có muốn search engine đánh chỉ mục (index) cho website của bạn hay không.

    Trang thiết lập chính của WordPress
    Trang thiết lập chính của WordPress

    Click chọn Install WordPress ở cuối trang, một biểu mẫu sẽ được hiển thị để bạn đăng nhập:

    Biểu mẫu đăng nhập
    Biểu mẫu đăng nhập

    Sau khi đăng nhập, bạn sẽ được truy cập đến trang dashboard quản lý của WordPress. Đến đây, bạn đã thành công trong việc cài đặt và thiết lập một ứng dụng WordPress cho riêng mình:

    Trang WordPress Dashboard
    Trang WordPress Dashboard

    Sau khi hoàn tất cài đặt WordPress qua Docker Compose, việc duy trì và tối ưu hóa website là rất quan trọng để đảm bảo tốc độ nhanh, bảo mật cao và khả năng mở rộng. Với dịch vụ WordPress Hosting của Vietnix sẽ giúp bạn quản lý website dễ dàng với WordPress Toolkit và tối ưu tốc độ với LiteSpeed Web Server. Đồng thời, dịch vụ hosting này còn cung cấp các công cụ bảo mật như File Locker và Imunify360 sẽ bảo vệ website khỏi mối đe dọa.

    Bước 7: Gia hạn chứng chỉ

    Các chứng chỉ của Let’s Encrypt có thời hạn là 90 ngày. Để website luôn được bảo mật, các bạn nên cấu hình cho các chứng chỉ được làm mới một cách tự động. Một trong những cách thực hiện là sử dụng job của trình lập lich cron. Trong phần tiếp theo, mình sẽ hướng dẫn cách tạo một cron job để chạy script hỗ trợ các bạn gia hạn chứng chỉ và cập nhật cấu hình Nginx theo định kỳ. Các bạn mở file script ssl_renew.sh:

    $ nano ssl_renew.sh

    Bạn thêm đoạn code sau vào file để script có khả năng làm mới chứng chỉ và cập nhật cấu hình Nginx. Các bạn thay username bằng username non-root của bạn:

    #!/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

    Trong đoạn code trên, bạn để script gán binary docker-compose cho biến COMPOSE với cờ --no-ansi nhằm chạy các lệnh docker-compose mà không cần sử dụng ANSI control characters (ký tự điều khiển ANSI). Điều tương tự được thực hiện với binary của docker. Tiếp theo, bạn sẽ cho script mở thư mục dự án ~/wordpress và chạy các lệnh docker-compose:

    • docker-compose run: Chạy một container certbot và ghi đè tùy chọn command đã định nghĩa trong service. Thay cho certonly, subcommand renew được sử dụng để gia hạn các chứng chỉ hết hiệu lực. Ngoài ra, bạn cũng bổ sung khả năng kiểm tra script với tùy chọn --dry-run.
    • docker-compose kill: Gửi tín hiệu SIGHUP đến container webserver để cập nhật lại cấu hình service.

    Cuối cùng, script sẽ gọi lệnh docker system prune để xóa toàn bộ các container và image không được sử dụng. Sau khi đóng và lưu lại các thay đổi của file, bạn cấp quyền thực thi cho script bằng lệnh:

    $ chmod +x ssl_renew.sh

    Bạn tiếp tục mở file root crontab để cấu hình cho script chạy định kỳ:

    $ sudo crontab -e

    Nếu đây là lần đầu chỉnh sửa, bạn sẽ được yêu cầu chọn một trình biên dịch để sử dụng:

    Output
    no crontab for root - using an empty one
    
    Select an editor.  To change later, run 'select-editor'.
      1. /bin/nano        <---- easiest
      2. /usr/bin/vim.basic
      3. /usr/bin/vim.tiny
      4. /bin/ed
    
    Choose 1-4 [1]:
    ...

    Bạn thêm dòng dưới đây vào cuối file root.

    ...
    */5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

    Hiện tại, để kiểm tra request gia hạn chứng chỉ có hoạt động hay không, bạn sẽ cấu hình cho job chạy script mỗi 5 phút. File cron.log được tạo để ghi lại các output liên quan của job.

    Sau 5 phút, bạn mở file cron.log và kiểm tra request gia hạn của mình:

    $ tail -f /var/log/cron.log

    Các bạn đã thành công nếu Output dưới đây được hiển thị:

    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)
    ** DRY RUN: simulating 'certbot renew' close to cert expiry
    **          (The test certificates above have not been saved.)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Bạn sử dụng tổ hợp phím Ctrl+C để thoát. Đến đây, bạn có thể cấu hình lại file crontab để job chạy script hằng ngày. Giả sử bạn cần chạy script vào mỗi buổi trưa, sửa lại dòng cuối cùng trong file như sau:

    ...
    0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

    Bạn nhớ xóa tùy chọn --dry-run trong script ssl_renew.sh:

    #!/bin/bash
    
    COMPOSE="/usr/local/bin/docker-compose --no-ansi"
    DOCKER="/usr/bin/docker"
    
    cd /home/sammy/wordpress/
    $COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
    $DOCKER system prune -af

    Job cron sẽ gia hạn các chứng chỉ Let’s Encrypt khi vẫn còn hiệu lực để đảm bảo các chứng chỉ không bị quá hạn. Bạn cũng có thể thiết lập Logrotate để luân phiên và nén các file log trong trường hợp cần thiết. Ngoài ra, bạn cũng có thể tham khảo thêm cách sử dụng Docker để cài đặt và triển khai Gitea trên Ubuntu một cách đơn giản và hiệu quả, một công cụ mã nguồn mở quản lý mã nguồn, trên Ubuntu bằng Docker, giúp tăng tính linh hoạt và độc lập cho dự án phát triển phần mềm của bạn.

    Vietnix – Nhà cung cấp dịch vụ hosting, VPS tốc độ cao

    Vietnix – Nhà cung cấp dịch vụ Hosting, VPS tốc độ cao được xây dựng trên nền tảng hạ tầng hiện đại, mang đến khả năng vận hành ổn định và tốc độ truy cập vượt trội cho website, ứng dụng. Ngoài ra, Vietnix còn tích hợp giải pháp backup tự động hàng tuần, tăng cường bảo mật và đảm bảo dữ liệu luôn được an toàn. Với sự đồng hành của đội ngũ kỹ thuật chuyên sâu hỗ trợ 24/7, bạn có thể yên tâm phát triển dự án mà không lo gián đoạn. Liên hệ ngay với Vietnix để nhận tư vấn và lựa chọn giải pháp tối ưu cho nhu cầu của bạn!

    Thông tin liên hệ:

    • Website: https://vietnix.vn/
    • Hotline: 1800 1093
    • Email: sales@vietnix.com.vn
    • Địa chỉ: 265 Hồng Lạc, Phường Bảy Hiền, Thành Phố Hồ Chí Minh

    Câu hỏi thường gặp

    Làm thế nào để triển khai Docker WordPress Nginx với hiệu suất tối ưu và dễ dàng mở rộng khi lượng truy cập tăng cao?

    Để triển khai Docker WordPress với Nginx hiệu quả và dễ mở rộng:
    Kiến trúc tách biệt service: Nginx (reverse proxy), PHP-FPM (WordPress), Database, Redis/Memcached (cache).
    Tối ưu hiệu suất: Bật FastCGI cache, dùng Redis/Memcached, kích hoạt OPcache, kết hợp CDN để giảm tải.
    Bảo mật & ổn định: Cài SSL (Let’s Encrypt), firewall, backup định kỳ.
    Mở rộng linh hoạt: Với traffic cao, dùng Docker Swarm hoặc Kubernetes để scale WordPress và Nginx, tách database ra hệ thống riêng, bổ sung load balancer và autoscaling.

    Cài đặt WordPress Nginx có ưu điểm gì so với WordPress chạy trên Apache?

    So với Apache, cài đặt WordPress trên Nginx mang lại một số ưu điểm nổi bật:
    Hiệu suất và tốc độ xử lý cao hơn: Nginx được thiết kế để xử lý hàng nghìn kết nối đồng thời với mức tiêu thụ tài nguyên thấp, giúp WordPress hoạt động nhanh và mượt hơn, đặc biệt khi có nhiều người truy cập cùng lúc.
    Tối ưu cho tĩnh và động: Nginx phục vụ file tĩnh (ảnh, CSS, JS) cực nhanh, giảm tải cho PHP và database, trong khi WordPress trên Apache dễ gặp tình trạng “nghẽn” khi lưu lượng tăng.
    Tiết kiệm tài nguyên: Với cùng cấu hình phần cứng, Nginx thường tiêu thụ CPU và RAM ít hơn, rất phù hợp cho VPS hoặc server có dung lượng hạn chế.
    Khả năng mở rộng tốt: Nginx dễ dàng kết hợp với các hệ thống cache như Redis, Memcached hoặc FastCGI Cache, giúp tăng tốc độ website đáng kể.
    Ổn định hơn khi tải lớn: Trong môi trường cần phục vụ lượng traffic cao (website tin tức, thương mại điện tử, forum), Nginx giúp WordPress giữ được sự ổn định mà Apache khó đáp ứng.

    Cảm ơn các bạn đã theo dõi bài viết, hy vọng qua bài hướng dẫn này, các bạn đã biết cách cài đặt WordPress bằng Docker Compose cho một web server Nginx, cũng như cách để bảo mật tên miền và gia hạn chứng chỉ trước khi hết hiệu lực. Nếu có bất kỳ thắc mắc hay phản hồi nào, các bạn hãy bình luận bên dưới, mình sẽ giải đáp nhanh nhất!

    THEO DÕI VÀ CẬP NHẬT CHỦ ĐỀ BẠN QUAN TÂM

    Đăng ký ngay để nhận những thông tin mới nhất từ blog của chúng tôi. Đừng bỏ lỡ cơ hội truy cập kiến thức và tin tức hàng ngày

    Đánh giá mức độ hữu ích của bài viết

    icon 1 sao

    Thất vọng

    icon 2 sao

    Chưa hữu ích

    icon 3 sao

    Bình thường

    icon 4 sao

    Hữu ích

    icon 5 sao

    Rất hữu ích

    Kết nối với mình qua

    Kết nối với mình qua

    Theo dõi
    Thông báo của
    guest
    0 Comments
    Phản hồi nội tuyến
    Xem tất cả bình luận

    Tăng tốc độ website - Nâng tầm giá trị thương hiệu

    Banner group
    Tăng tốc tải trang

    95 điểm

    Nâng cao trải nghiệm người dùng

    Tăng 8% tỷ lệ chuyển đổi

    Thúc đẩy SEO, Google Ads hiệu quả

    Tăng tốc ngay

    SẢN PHẨM NỔI BẬT

    Icon tab

    MAXSPEED HOSTING

    TĂNG TỐC WEBSITE TOÀN DIỆN

    CÔNG NGHỆ ĐỘC QUYỀN

    Vector

    PHẦN CỨNG MẠNH MẼ

    Vector

    HỖ TRỢ 24/7

    Vector
    ĐĂNG KÝ NGAYGroup icon
    khuyến mãi tháng 10
    Nhanh tay, số lượng có hạn!
    01/10/2025 - 31/10/2025
    Pattern

    7 NGÀY DÙNG THỬ HOSTING

    NẮM BẮT CƠ HỘI, THÀNH CÔNG DẪN LỐI

    Cùng trải nghiệm dịch vụ hosting tốc độ cao được hơn 100,000 khách hàng sử dụng

    icon popup single post

    CẢM ƠN BẠN ĐÃ ĐÁNH GIÁ BÀI VIẾT

    Vietnix sẽ luôn cố gắng cải thiện chất lượng dịch vụ mỗi ngày

    ĐÓNG

    Đánh giá mức độ hữu ích của bài viết

    icon 1 sao

    Thất vọng

    icon 2 sao

    Chưa hữu ích

    icon 3 sao

    Bình thường

    icon 4 sao

    Hữu ích

    icon 5 sao

    Rất hữu ích

    Icon
    ĐĂNG KÝ NHẬN TÀI LIỆU THÀNH CÔNG
    Cảm ơn bạn đã đăng ký nhận tài liệu mới nhất từ Vietnix!
    ĐÓNG

    ĐĂNG KÝ DÙNG THỬ HOSTING

    Asset

    7 NGÀY MIỄN PHÍ

    Asset 1

    ĐĂNG KÝ DÙNG THỬ HOSTING

    Asset

    7 NGÀY MIỄN PHÍ

    Asset 1
    Icon
    XÁC NHẬN ĐĂNG KÝ DÙNG THỬ THÀNH CÔNG
    Cảm ơn bạn đã đăng ký thông tin thành công. Đội ngũ CSKH sẽ liên hệ trực tiếp để kích hoạt dịch vụ cho bạn nhanh nhất!
    ĐÓNG