Mục lục

Tham gia kênh Telegram của CloudFly để nhận thêm ưu đãi và không bỏ lỡ bất kỳ khuyến mãi nào từ CloudFly

Hướng dẫn cài đặt WordPress với Docker Compose

Ngày đăng: July 17, 2025

Ubuntu

description image

Giới thiệu

WordPress là một hệ quản trị nội dung (CMS) miễn phí và mã nguồn mở, được xây dựng trên cơ sở dữ liệu MySQL cùng xử lý PHP. Nhờ kiến trúc plugin có thể mở rộng và hệ thống mẫu, hầu hết việc quản trị có thể thực hiện qua giao diện web. Đây là lý do WordPress được ưa chuộng khi tạo các loại website khác nhau, từ blog đến trang sản phẩm và các trang thương mại điện tử.

Thường khi chạy WordPress, bạn cần cài đặt một ngăn xếp LAMP (Linux, Apache, MySQL và PHP) hoặc LEMP (Linux, Nginx, MySQL và PHP), có thể tốn thời gian. Tuy nhiên, bằng cách sử dụng các công cụ như Docker và Docker Compose, bạn có thể đơn giản hóa quá trình thiết lập ngăn xếp ưu tiên và cài đặt WordPress. Thay vì tự tay cài từng thành phần riêng lẻ, bạn có thể sử dụng các images, chuẩn hóa các thư viện, tệp cấu hình và biến môi trường, sau đó chạy trong các containers - các tiến trình riêng biệt trên hệ điều hành dùng chung. Ngoài ra với Docker Compose, bạn có thể phối hợp nhiều containers như ứng dụng và cơ sở dữ liệu để giao tiếp với nhau.

Trong hướng dẫn này, bạn sẽ xây dựng một bộ cài WordPress đa container gồm cơ sở dữ liệu MySQL, máy chủ web Nginx và chính WordPress. Bạn cũng sẽ bảo mật cài đặt bằng việc lấy chứng chỉ TLS/SSL từ Let's Encrypt cho domain bạn chọn. Cuối cùng, bạn sẽ lên lịch tác vụ cron để tự động gia hạn chứng chỉ nhằm giữ cho domain của bạn luôn an toàn.

Yêu cầu trước khi bắt đầu

Nếu bạn đang dùng Ubuntu phiên bản 16.04 hoặc thấp hơn, nên nâng cấp lên phiên bản mới hơn vì Ubuntu không còn hỗ trợ các phiên bản này. Bộ hướng dẫn nâng cấp Ubuntu sẽ giúp bạn thực hiện việc này.

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

  • Một máy chủ chạy Ubuntu kèm người dùng không phải root có quyền sudo và firewall đang hoạt động. Hướng dẫn thiết lập trên các bản phân phối có trong danh sách và 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 trong hướng dẫn "Cách cài và sử dụng Docker trên Ubuntu" các phiên bản 22.04 / 20.04 / 18.04.
  • Docker Compose được cài đặt trên máy chủ theo bước đầu tiên trong hướng dẫn "Cách cài Docker Compose trên Ubuntu" các phiên bản 22.04 / 20.04 / 18.04.
  • Một tên miền đã đăng ký; hướng dẫn sử dụng tên miền giả định your_domain. Bạn có thể lấy miễn phí tại Freenom hoặc nhà đăng ký tên miền khác bạn chọn.
  • Cấu hình hai bản ghi DNS cho máy chủ:
    • Bản ghi A với tên your_domain trỏ đến địa chỉ IP công cộng của server.
    • Bản ghi A với tên www.your_domain trỏ đến địa chỉ IP công cộng của server.

Sau khi chuẩn bị xong, bạn có thể bắt đầu bước đầu tiên.

Các bước cài đặt WordPress với Docker Compose

  1. Định nghĩa cấu hình máy chủ web
  2. Đặt biến môi trường
  3. Định nghĩa các dịch vụ trong Docker Compose
  4. Lấy chứng chỉ SSL
  5. Sửa đổi cấu hình máy chủ web và định nghĩa dịch vụ
  6. Hoàn thành cài đặt qua giao diện web
  7. Thiết lập gia hạn chứng chỉ tự động

Bước 1 — Định nghĩa cấu hình máy chủ web

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

Tạo thư mục dự án cho cài đặt WordPress, ví dụ đặt tên wordpress (bạn có thể đặt tên khác):

$ mkdir wordpress

Di chuyển vào thư mục:

$ cd wordpress

Tạo thư mục chứa tệp cấu hình:

$ mkdir nginx-conf

Mở tệp cấu hình để chỉnh sửa:

$ nano nginx-conf/nginx.conf

Trong tệp này, thêm một khối server với chỉ dẫn tên máy chủ và thư mục gốc, cùng các khối vị trí xử lý xác minh chứng chỉ Certbot, xử lý PHP và các yêu cầu tài nguyên tĩnh.

Thêm đoạn mã sau vào tệp, thay thế your_domain bằng tên miền thực tế của bạn:

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

Khối server bao gồm:

  • listen: Nginx lắng nghe cổng 80 để hỗ trợ plugin webroot của Certbot cho yêu cầu chứng chỉ.
  • server_name: Tên server thay bằng domain thật của bạn.
  • index: Định nghĩa thứ tự ưu tiên các tệp index, ưu tiên index.php.
  • root: Thư mục gốc cho các yêu cầu.

Các khối vị trí xử lý:

  • location ~ /.well-known/acme-challenge: Xử lý xác minh chứng chỉ của Certbot.
  • location /: Kiểm tra tệp theo URI và chuyển sang WordPress khi không tìm thấy.
  • location ~ \.php$: Xử lý các yêu cầu PHP thông qua FastCGI tới container wordpress.
  • location ~ /\.ht: Từ chối phục vụ các tệp .htaccess.
  • location = /favicon.ico, location = /robots.txt: Tắt ghi log các yêu cầu đến.
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: Tắt log và enable cache cho tài nguyên tĩnh.

Lưu và đóng tệp.

Tiếp theo, bạn sẽ định nghĩa biến môi trường cho container ứng dụng và cơ sở dữ liệu.

Bước 2 — Đặt biến môi trường

Container cơ sở dữ liệu và ứng dụng WordPress cần truy cập các biến môi trường khi runtime để lưu trữ và sử dụng dữ liệu ứng dụng. Bao gồm cả thông tin nhạy cảm như mật khẩu root MySQL và tài khoản người dùng cơ sở dữ liệu cùng mật khẩu, cũng như thông tin không nhạy cảm như tên database và host.

Thay vì đặt tất cả biến trong tệp docker-compose.yml, biến nhạy cảm bạn nên đặt trong tệp .env và hạn chế chia sẻ để tránh lộ thông tin.

Tạo và mở file .env trong thư mục dự án wordpress:

$ nano .env

Thêm các biến sau (thay thế bằng giá trị của bạn):

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

Lưu và đóng.

Chắc chắn rằng file .env nằm trong .gitignore và .dockerignore để tránh bị đưa lên kho Git hoặc vào image Docker.

Tạo các file này nếu chưa có:

$ nano .gitignore

Thêm vào:

.env

$ nano .dockerignore

Thêm vào:

.env
.git
docker-compose.yml
.dockerignore

Lưu và đóng.

Bây giờ bạn đã sẵn sàng định nghĩa các dịch vụ trong docker-compose.yml.

Bước 3 — Định nghĩa các dịch vụ trong Docker Compose

Mở tệp docker-compose.yml trong thư mục wordpress:

$ nano docker-compose.yml

Thêm cấu hình phiên bản và dịch vụ database:

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:

  • image: chỉ định image mysql phiên bản 8.0
  • container_name: tên container
  • restart: tự động khởi động lại khi không bị dừng thủ công
  • env_file: lấy biến môi trường trong .env
  • environment: thêm biến MYSQL_DATABASE
  • volumes: gắn volume lưu trữ dữ liệu mysql
  • command: cấu hình xác thực dùng mysql_native_password do WordPress không hỗ trợ cơ chế mặc định MySQL 8
  • networks: nối vào mạng riêng app-network

Tiếp tục thêm dịch vụ 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

Chú ý:

  • depends_on: đảm bảo container db chạy trước
  • image: dùng image WordPress với php-fpm và Alpine nhỏ gọn
  • environment: sử dụng biến trong .env và gán tên host là container db với cổng 3306
  • volumes: gắn volume wordpress
  • networks: kết nối cùng mạng app-network

Thêm 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
  • ports: expose cổng 80
  • volumes: mount code wordpress, cấu hình nginx, và thư mục chứng chỉ let’s encrypt

Dịch vụ certbot để lấy chứng chỉ:

  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

Trong đó cần thay sammy@your_domain và your_domain bằng email và domain của bạn. Lệnh certonly sử dụng plugin webroot để lấy chứng chỉ.

Phần cuối file khai báo volumes và networks:

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

Lưu và đóng tệp.

Bạn sẽ dùng docker-compose up để khởi tạo và chạy các container.

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

Chạy lệnh sau để tạo và chạy các container:

$ docker-compose up -d

Kiểm tra trạng thái dịch vụ:

$ docker-compose ps

Nếu thành công, db, wordpress, webserver hiện trạng thái Up, certbot trạng thái Exit 0 (do chạy xong lệnh certonly).

Kiểm tra thư mục chứng chỉ:

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

Nếu đã có thư mục domain, có nghĩa là chứng chỉ đã được tạo.

Bây giờ sửa lại docker-compose.yml, thay --staging thành --force-renewal trong lệnh certbot để lấy chứng chỉ thật:

Tiếp theo chạy lại:

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

Kiểm tra thông báo thành công lấy chứng chỉ.

Bước 5 — Sửa cấu hình máy chủ web và dịch vụ

Dừng container webserver:

$ docker-compose stop webserver

Tải các tham số bảo mật SSL của Nginx từ Certbot:

$ curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

Xóa file cấu hình nginx cũ:

$ rm nginx-conf/nginx.conf

Tạo lại nginx.conf mới có hỗ trợ redirect HTTP sang HTTPS và SSL (thay your_domain bằng domain của bạn):

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;

    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ập nhật docker-compose.yml, thêm port 443 cho webserver:

ports:
  - "80:80"
  - "443:443"

Khởi động lại webserver:

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

Kiểm tra dịch vụ chạy:

$ docker-compose ps

Bước 6 — Hoàn thành cài đặt qua giao diện web

Mở trình duyệt truy cập https://your_domain (đổi thành domain của bạn)

Chọn ngôn ngữ, sau đó tạo tên site, chọn username (không nên dùng admin), mật khẩu mạnh, nhập email và cài đặt SEO theo ý muốn.

Cài đặt xong, đăng nhập vào dashboard WordPress và quản trị website.

Bước 7 — Gia hạn chứng chỉ tự động

Chứng chỉ Let's Encrypt có hiệu lực 90 ngày, cần tự động gia hạn để không bị hết hạn.

Tạo script gia hạn ssl_renew.sh trong thư mục wordpress:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

Thay sammy thành tên người dùng không phải root của bạn.

Đặt quyền thực thi:

$ chmod +x ssl_renew.sh

Thêm tác vụ cron để chạy script này định kỳ:

$ sudo crontab -e

Thêm dòng (chạy mỗi 5 phút để test):

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

Kiểm tra nhật ký sau 5 phút để đảm bảo việc gia hạn thực hiện thành công:

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

Sau khi test thành công, bạn có thể đặt chạy 1 lần mỗi ngày (ví dụ chạy lúc 12h trưa):

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

Đồng thời xóa tùy chọn --dry-run trong script ssl_renew.sh để thực hiện gia hạn thật.

Bạn cũng nên cấu hình logrotate để quản lý nhật ký cron.

Kết luận

Trong hướng dẫn này, bạn đã sử dụng Docker Compose để tạo bộ cài WordPress với máy chủ Nginx, lấy chứng chỉ TLS/SSL cho domain, và thiết lập cron để tự động gia hạn chứng chỉ.

Bạn có thể tham khảo thêm các bài viết để cải thiện hiệu năng và sao lưu tài nguyên WordPress, hoặc thử tìm hiểu cách cài đặt WordPress trên Kubernetes bằng Helm để khám phá quy trình container hóa nâng cao.

Tham gia kênh Telegram của CloudFly để nhận thêm ưu đãi và không bỏ lỡ bất kỳ khuyến mãi nào từ CloudFly
Chia sẻ

0 câu trả lời