Site icon Cung cấp dịch vụ Cloud VPS, Server, Hosting Việt Nam & Thế giới

Hướng Dẫn Cài Đặt WordPress Với Docker Compose Chi Tiết Nhất 2025

Cài Đặt WordPress Với Docker Compose

WordPress là một hệ quản trị nội dung (CMS) mã nguồn mở và miễn phí, được phát triển trên nền tảng MySQLPHP. Nhờ vào kiến trúc mở với plugin và hệ thống mẫu, hầu hết các tác vụ quản lý có thể thực hiện trực tiếp qua giao diện web, điều này giúp WordPress trở thành một lựa chọn phổ biến để xây dựng nhiều loại website, từ blog cá nhân, trang giới thiệu sản phẩm cho đến các cửa hàng thương mại điện tử.

Thông thường, việc triển khai WordPress yêu cầu cài đặt một stack LAMP (Linux, Apache, MySQL, PHP) hoặc LEMP (Linux, Nginx, MySQL, PHP), quá trình này có thể tốn nhiều thời gian. Tuy nhiên, với các công cụ như Docker và Docker Compose, bạn có thể đơn giản hóa quá trình cài đặt. Thay vì cài đặt từng thành phần riêng lẻ, bạn có thể sử dụng các image Docker chuẩn, giúp đồng bộ hóa các thư viện, cấu hình và biến môi trường, rồi chạy chúng trong các container – các tiến trình tách biệt nhưng chia sẻ cùng hệ điều hành. Bằng cách sử dụng Docker Compose, bạn có thể phối hợp nhiều container, ví dụ như ứng dụng và cơ sở dữ liệu, để chúng có thể giao tiếp hiệu quả.

Bạn muốn xây dựng website WordPress chuyên nghiệp? Hãy bắt đầu bằng cách mua VPS chất lượng cao để đảm bảo hiệu suất và bảo mật. Với VPS, bạn dễ dàng cài đặt Docker Compose, tối ưu hóa WordPress, mang đến trải nghiệm mượt mà cho người dùng. Khám phá các gói VPS ngay hôm nay!

Trong bài hướng dẫn này, bạn sẽ xây dựng một cài đặt WordPress với nhiều container, bao gồm MySQL, Nginx và chính WordPress. Bạn cũng sẽ bảo mật hệ thống bằng cách cài đặt chứng chỉ TLS/SSL từ Let’s Encrypt cho tên miền của mình. Cuối cùng, bạn sẽ cấu hình cron job để tự động gia hạn chứng chỉ, giúp bảo vệ website của bạn luôn được bảo mật.

Yêu Cầu

Nếu bạn đang sử dụng Ubuntu phiên bản 16.04 trở xuống, chúng tôi khuyến nghị bạn nâng cấp lên phiên bản mới nhất vì Ubuntu không còn hỗ trợ những phiên bản cũ này. Bộ sưu tập hướng dẫn này sẽ hỗ trợ bạn trong việc nâng cấp phiên bản Ubuntu.

Để theo dõi hướng dẫn này, bạn cần:

● Một máy chủ chạy Ubuntu, kèm theo một người dùng không phải root có quyền sudo và một firewall đang hoạt động. Để được hướng dẫn thiết lập, vui lòng chọn bản phân phối của bạn trong danh sách và làm theo Hướng Dẫn Thiết Lập Máy Chủ Ban Đầu.

● Docker được cài đặt trên máy chủ, theo các bước 1 và 2 của “Cách Cài Đặt và Sử Dụng Docker trên Ubuntu” 22.04 / 20.04 / 18.04.

● Docker Compose được cài đặt trên máy chủ, theo bước 1 của “Cách Cài Đặt Docker Compose trên Ubuntu” 22.04 / 20.04 / 18.04.

● Một tên miền đã được đăng ký. Hướng dẫn này sẽ sử dụng your_domain như một tên miền mẫu. Bạn có thể đăng ký miễn phí tại Freenom hoặc sử dụng nhà đăng ký tên miền mà bạn thích.

● Cả hai bản ghi DNS sau đã được thiết lập cho máy chủ của bạn. Bạn có thể theo dõi phần giới thiệu về DNS của DataOnline để biết cách thêm chúng vào tài khoản DataOnline:

Khi bạn đã thiết lập xong mọi thứ, bạn đã sẵn sàng bắt đầu bước đầu tiên.

Bước 1 – Xác định cấu hình máy chủ Web

Trước khi chạy bất kỳ container nào, bước đầu tiên của bạn là xác định cấu hình cho máy chủ web Nginx. Tệp cấu hình của bạn sẽ bao gồm một số khối location đặc trưng cho WordPress, cùng với một khối location để chuyển hướng các yêu cầu xác minh của Let’s Encrypt tới Certbot để gia hạn chứng chỉ tự động.

Đầu tiên, tạo một thư mục dự án cho cài đặt WordPress của bạn. Trong ví dụ này, thư mục được đặt tên là wordpress. Bạn có thể đặt tên khác nếu muốn:

mkdir wordpress

Sau đó, di chuyển vào thư mục:

cd wordpress

Tiếp theo, tạo một thư mục cho tệp cấu hình:

mkdir nginx-conf

Mở tệp cấu hình với nano (hoặc trình soạn thảo ưa thích của bạn):

nano nginx-conf/nginx.conf

Trong tệp này, thêm một khối server với các chỉ thị cho tên máy chủ và thư mục gốc, cùng với các khối location để chuyển hướng yêu cầu của Certbot, xử lý PHP và phục vụ các tài sản tĩnh.

Thêm đoạn mã sau vào tệp. Hãy nhớ thay thế your_domain bằng tên miền của bạn:

~/wordpress/nginx-conf/nginx.conf
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:

Để biết thêm thông tin về proxy FastCGI, hãy đọc “Hiểu và Triển khai FastCGI Proxying trong Nginx.”. Để biết thêm về các khối server và location, hãy xem “Understanding Nginx Server and Location Block Selection Algorithms”.

Sau khi hoàn tất chỉnh sửa, lưu và đóng tệp. Nếu bạn dùng nano, nhấn CTRL+X, Y, sau đó ENTER.

Với cấu hình Nginx đã sẵn sàng, bạn có thể chuyển sang tạo các biến môi trường để truyền vào container ứng dụng và cơ sở dữ liệu tại thời điểm chạy.

Bước 2 – Xác định các biến môi trường

Các container cơ sở dữ liệu và ứng dụng WordPress của bạn sẽ cần truy cập vào một số biến môi trường tại thời điểm chạy để dữ liệu ứng dụng của bạn được lưu trữ và truy cập. Các biến này bao gồm cả thông tin nhạy cảm và không nhạy cảm: giá trị nhạy cảm cho mật khẩu root của MySQL và tên người dùng cùng mật khẩu của cơ sở dữ liệu ứng dụng, và thông tin không nhạy cảm cho tên cơ sở dữ liệu và máy chủ.

Thay vì đặt tất cả các giá trị này trong tệp Docker Compose – tệp chính chứa thông tin về cách các container của bạn sẽ chạy – bạn hãy đặt các giá trị nhạy cảm trong tệp .env và hạn chế việc lưu hành nó. Điều này sẽ ngăn các giá trị này bị sao chép vào kho lưu trữ dự án và bị lộ ra ngoài.

Trong thư mục dự án chính, ~/wordpress, mở một tệp có tên .env:

nano .env

Trong tệp này, bạn sẽ đặt các giá trị bí mật bao gồm mật khẩu cho người dùng root của MySQL, cũng như tên người dùng và mật khẩu mà WordPress sẽ sử dụng để truy cập cơ sở dữ liệu.

Thêm các biến và giá trị sau vào tệp. Hãy nhớ thay thế các giá trị mẫu bằng giá trị thực của bạn:

~/wordpress/.env
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

Ở đây, bạn đã bao gồm mật khẩu cho tài khoản quản trị root, cùng với tên người dùng và mật khẩu ưa thích cho cơ sở dữ liệu ứng dụng của bạn.

Lưu và đóng tệp khi bạn đã hoàn tất chỉnh sửa.

Vì tệp .env chứa thông tin nhạy cảm, bạn cần đảm bảo rằng nó được thêm vào các tệp .gitignore.dockerignore của dự án. Điều này sẽ báo cho Git và Docker biết những tệp nào không được sao chép vào kho lưu trữ Git và image Docker.

Nếu bạn dự định sử dụng Git cho việc kiểm soát phiên bản, hãy khởi tạo thư mục làm việc hiện tại của bạn như một repository với:

git init

Sau đó tạo và mở tệp .gitignore:

nano .gitignore

Thêm dòng sau vào tệp:

~/wordpress/.gitignore
.env

Lưu và đóng tệp sau khi chỉnh sửa.

Tương tự, bạn nên thêm .env vào tệp .dockerignore để đảm bảo nó không bị đưa lên container khi sử dụng thư mục này làm build context.

Mở tệp:

nano .dockerignore

Thêm dòng sau vào tệp:

~/wordpress/.dockerignore
.env

Ngoài ra, bạn có thể thêm các tệp và thư mục liên quan đến phát triển ứng dụng của bạn vào:

~/wordpress/.dockerignore
.env
.git
docker-compose.yml
.dockerignore

Lưu và đóng tệp khi bạn đã hoàn tất.

Với thông tin nhạy cảm đã được thiết lập, bạn có thể chuyển sang xác định các dịch vụ trong tệp docker-compose.yml.

Bước 3 – Xác định các dịch vụ với Docker Compose

Tệp docker-compose.yml của bạn sẽ chứa các định nghĩa dịch vụ cho cài đặt này. Một dịch vụ trong Compose là một container đang chạy, và định nghĩa dịch vụ xác định thông tin về cách mỗi container sẽ chạy.

Sử dụng Compose, bạn có thể định nghĩa các dịch vụ khác nhau để chạy ứng dụng đa container, vì Compose cho phép bạn liên kết các dịch vụ này với nhau thông qua mạng và volume chia sẻ. Điều này rất hữu ích trong cài đặt hiện tại, vì bạn sẽ tạo các container riêng biệt cho cơ sở dữ liệu, ứng dụng WordPress và máy chủ web. Bạn cũng sẽ tạo một container để chạy Certbot nhằm lấy chứng chỉ cho máy chủ web.

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

nano docker-compose.yml

Thêm đoạn mã sau để định nghĩa phiên bản Compose và dịch vụ cơ sở dữ liệu (db):

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

Giải Thích về dịch vụ db:

Tiếp theo, ngay dưới định nghĩa dịch vụ db, thêm định nghĩa cho dịch vụ ứng dụng 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

Giải Thích về dịch vụ wordpress:

Sau đó, ngay dưới định nghĩa dịch vụ wordpress, thêm định nghĩa cho dịch vụ máy chủ web Nginx:

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

Giải Thích về dịch vụ webserver:

Cuối cùng, ngay dưới định nghĩa dịch vụ webserver, thêm định nghĩa cho dịch vụ certbot:

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

Giải Thích về dịch vụ certbot:

Dịch vụ này kéo image certbot/certbot từ Docker Hub và sử dụng các volume để chia sẻ tài nguyên với container Nginx, bao gồm chứng chỉ và khóa (volume certbot-etc) và mã ứng dụng WordPress (volume wordpress).

Tiếp theo, bên dưới định nghĩa dịch vụ, thêm phần định nghĩa cho network và volumes:

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

Giải Thích:

Dưới đây là tệp docker-compose.yml hoàn chỉnh:

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

Lưu và đóng tệp khi đã chỉnh sửa xong.

Với các định nghĩa dịch vụ đã sẵn sàng, bạn đã sẵn sàng khởi động các container và kiểm tra yêu cầu chứng chỉ.

Bước 4 – Lấy chứng chỉ SSL và thông tin xác thực

Khởi chạy các container bằng lệnh docker-compose up, lệnh này sẽ tạo và chạy các container theo thứ tự bạn đã chỉ định. Bằng cách thêm tham số -d, lệnh sẽ chạy các container db, wordpresswebserver ở chế độ nền:

docker-compose up -d

Đầu ra dưới đây xác nhận rằng các dịch vụ của bạn đã được tạo:

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

Sử dụng lệnh docker-compose ps để kiểm tra trạng thái của các dịch vụ:

docker-compose ps

Khi hoàn tất, các dịch vụ db, wordpresswebserver của bạn sẽ ở trạng thái Up và container certbot sẽ thoát với thông báo trạng thái 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

Bất kỳ trạng thái nào khác ngoài Up trong cột State của các dịch vụ db, wordpress hoặc webserver, hoặc mã thoát khác ngoài 0 đối với container certbot có nghĩa là bạn có thể cần kiểm tra nhật ký của dịch vụ bằng lệnh docker-compose logs:

docker-compose logs service_name

Bạn có thể kiểm tra rằng chứng chỉ của bạn đã được mount vào container webserver bằng lệnh docker-compose exec:

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

Khi các yêu cầu chứng chỉ của bạn thành công, đầu ra sẽ như sau:

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

Giờ bạn đã biết yêu cầu của mình sẽ thành công, bạn có thể chỉnh sửa định nghĩa dịch vụ certbot để loại bỏ tham số --staging.

Mở file docker-compose.yml:

nano docker-compose.yml

Tìm phần trong file có định nghĩa dịch vụ certbot, và thay thế tham số --staging trong tùy chọn command bằng tham số --force-renewal, lệnh này sẽ báo cho Certbot rằng bạn muốn yêu cầu một chứng chỉ mới với cùng các tên miền như chứng chỉ đã có. Dưới đây là định nghĩa dịch vụ certbot với tham số đã được cập nhật:

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

Bây giờ, bạn có thể chạy lệnh docker-compose up để tạo lại container certbot. Bạn cũng sẽ thêm tham số --no-deps để báo cho Compose rằng có thể bỏ qua việc khởi động dịch vụ webserver, vì nó đã đang chạy:

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

Đầu ra dưới đây cho biết rằng yêu cầu chứng chỉ của bạn đã 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

Với chứng chỉ đã được thiết lập, bạn có thể chuyển sang chỉnh sửa cấu hình Nginx để thêm SSL.

Bước 5 – Chỉnh sửa cấu hình máy chủ Web và định nghĩa dịch vụ

Việc kích hoạt SSL trong cấu hình Nginx sẽ bao gồm việc thêm chuyển hướng HTTP sang HTTPS, chỉ định vị trí của chứng chỉ SSL và khóa, cũng như thêm các tham số bảo mật và header.

Vì bạn sẽ tạo lại dịch vụ webserver để bao gồm những bổ sung này, bạn có thể dừng dịch vụ hiện tại:

docker-compose stop webserver

Trước khi chỉnh sửa file cấu hình, hãy lấy các tham số bảo mật Nginx được khuyến nghị từ Certbot bằng lệnh curl:

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

Lệnh này sẽ lưu các tham số vào file options-ssl-nginx.conf, nằm trong thư mục nginx-conf.

Tiếp theo, hãy xóa file cấu hình Nginx mà bạn đã tạo trước đó:

rm nginx-conf/nginx.conf

Tạo và mở một phiên bản khác của file:

nano nginx-conf/nginx.conf

Thêm đoạn mã sau vào file để chuyển hướng HTTP sang HTTPS và thêm các thông tin SSL (vị trí chứng chỉ, khóa, các tham số và header bảo mật). Nhớ thay your_domain bằng tên miền của bạn:

~/wordpress/nginx-conf/nginx.conf
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;
        }
}

Khối máy chủ HTTP (HTTP server block) chỉ định webroot cho các yêu cầu gia hạn của Certbot đến thư mục .well-known/acme-challenge. Nó cũng bao gồm chỉ thị rewrite để chuyển hướng các yêu cầu HTTP đến HTTPS.

Khối này cũng bao gồm vị trí của chứng chỉ SSL và khóa, cùng với các tham số bảo mật được Certbot khuyến nghị mà bạn đã lưu ở file nginx-conf/options-ssl-nginx.conf.

Ngoài ra, nó còn bao gồm một số header bảo mật giúp bạn đạt xếp hạng A trên các trang kiểm tra như SSL Labs và Security Headers. Các header này bao gồm: X-Frame-Options, X-Content-Type-Options, Referrer Policy, Content-Security-PolicyX-XSS-Protection. Header HTTP Strict Transport Security (HSTS) được chú thích – chỉ kích hoạt nếu bạn hiểu rõ các tác động và đã đánh giá tính năng “preload” của nó.

Các chỉ thị rootindex cũng nằm trong khối này, cùng với các khối định vị (location block) dành riêng cho WordPress được đề cập trong Bước 1.

Sau khi hoàn tất chỉnh sửa, lưu lại và đóng file.

Trước khi tạo lại dịch vụ webserver, bạn cần thêm ánh xạ cổng 443 vào định nghĩa dịch vụ webserver.

Mở file docker-compose.yml:

nano docker-compose.yml

Trong định nghĩa dịch vụ webserver, thêm ánh xạ cổng 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

Dưới đây là file docker-compose.yml đầy đủ sau các 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

Lưu và đóng file khi đã hoàn tất chỉnh sửa.

Tạo lại dịch vụ webserver:

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

Kiểm tra các dịch vụ bằng lệnh docker-compose ps:

docker-compose ps

Đầu ra nên hiển thị rằng các dịch vụ db, wordpresswebserver đang chạ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

Với các container đã chạy, bạn có thể hoàn tất cài đặt WordPress thông qua giao diện web.

Bước 6 – Hoàn tất cài đặt qua giao diện Web

Với các container đang chạy, tiến hành hoàn tất cài đặt thông qua giao diện WordPress trên web.

Trong trình duyệt, hãy truy cập vào tên miền máy chủ của bạn. Nhớ thay your_domain bằng tên miền của riêng bạn:

https://your_domain

Chọn ngôn ngữ mà bạn muốn sử dụng:

Sau khi nhấn Continue, bạn sẽ đến trang cài đặt chính, nơi bạn cần đặt tên cho trang web và đặt tên người dùng. Nên chọn tên người dùng dễ nhớ (không phải “admin”) và mật khẩu mạnh. Bạn có thể sử dụng mật khẩu WordPress tự động tạo hoặc tạo mật khẩu của riêng mình.

Cuối cùng, bạn cần nhập địa chỉ email và quyết định có cho phép công cụ tìm kiếm lập chỉ mục cho trang web của bạn hay không:

Nhấn nút Install WordPress ở cuối trang sẽ đưa bạn đến trang đăng nhập:

Khi đã đăng nhập, bạn sẽ có quyền truy cập vào bảng điều khiển quản trị WordPress:

Với cài đặt WordPress hoàn tất, bạn có thể thực hiện các bước tiếp theo để đảm bảo rằng chứng chỉ SSL của bạn sẽ được gia hạn tự động.

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

Chứng chỉ Let’s Encrypt có giá trị 90 ngày. Bạn có thể thiết lập một quy trình gia hạn tự động để đảm bảo chúng không hết hạn. Một cách làm là tạo một công việc với tiện ích lập lịch cron. Trong ví dụ sau, bạn sẽ tạo một cron job để chạy định kỳ một script nhằm gia hạn chứng chỉ và tải lại cấu hình Nginx.

Đầu tiên, mở file script có tên ssl_renew.sh:

nano ssl_renew.sh

Thêm đoạn mã sau vào script để gia hạn chứng chỉ và tải lại cấu hình máy chủ web. Nhớ thay thế tên người dùng không phải root (trong ví dụ là sammy) bằng tên người dùng 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

Script này đầu tiên gán binary của docker-compose cho biến COMPOSE, với tùy chọn --no-ansi để chạy lệnh mà không có ký tự điều khiển ANSI. Sau đó, nó làm tương tự với binary của docker. Cuối cùng, nó chuyển đến thư mục dự án ~/wordpress và chạy các lệnh docker-compose như sau:

Sau đó, nó chạy lệnh docker system prune để xóa tất cả các container và image không sử dụng.

Đóng file khi đã hoàn tất chỉnh sửa. Hãy làm cho file này có thể thực thi bằng lệnh sau:

chmod +x ssl_renew.sh

Tiếp theo, mở file crontab của root để chạy script gia hạn theo khoảng thời gian xác định:

sudo crontab -e

Nếu đây là lần đầu tiên bạn chỉnh sửa file này, bạn sẽ được yêu cầu chọn một trình soạn thảo:

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

Ở cuối file crontab, thêm dòng sau:

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

Dòng này sẽ thiết lập cron job chạy mỗi 5 phút, giúp bạn kiểm tra xem yêu cầu gia hạn có hoạt động như mong đợi không. Một file log có tên cron.log sẽ được tạo để ghi lại các thông tin đầu ra liên quan đến job.

Sau 5 phút, kiểm tra file cron.log để xác nhận yêu cầu gia hạn đã thành công hay chưa:

tail -f /var/log/cron.log

Đầu ra dưới đây xác nhận việc gia hạn thành công:

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

Thoát bằng cách nhấn CTRL+C trong terminal.

Bạn có thể chỉnh sửa file crontab để thiết lập chạy hàng ngày. Ví dụ, để chạy script vào lúc 12 giờ trưa hàng ngày, bạn có thể sửa dòng cuối file như sau:

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

Bạn cũng nên loại bỏ tham số --dry-run khỏi 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

Cron job của bạn sẽ đảm bảo rằng chứng chỉ Let’s Encrypt không bị hết hạn bằng cách gia hạn chúng khi đủ điều kiện. Bạn cũng có thể thiết lập log rotation bằng tiện ích Logrotate trên Ubuntu 22.04 / 20.04 để nén và xoay vòng các file log của bạn.

Kết luận

Trong hướng dẫn này, bạn đã sử dụng Docker Compose để triển khai một môi trường WordPress hoàn chỉnh, bao gồm máy chủ web Nginx và cơ sở dữ liệu MySQL. Bạn cũng đã thiết lập bảo mật cho trang web bằng cách lấy chứng chỉ TLS/SSL từ Let’s Encrypt và liên kết nó với tên miền mong muốn. Để đảm bảo tính liên tục và an toàn, bạn đã cấu hình một cron job tự động gia hạn chứng chỉ, giúp duy trì bảo mật mà không cần can thiệp thủ công. Với những kiến thức đã học, bạn có thể tiếp tục mở rộng và tùy chỉnh môi trường WordPress của mình để đáp ứng các nhu cầu cụ thể.

Để triển khai WordPress với Docker Compose hiệu quả, việc thuê VPS giá rẻ là lựa chọn thông minh. VPS giá rẻ cung cấp tài nguyên mạnh mẽ, hỗ trợ cài đặt nhanh chóng, giúp tiết kiệm chi phí mà vẫn đảm bảo website vận hành ổn định. Tìm hiểu gói VPS phù hợp ngay!

Exit mobile version