自行透過 Docker 建立 WordPress 網站


Heresy 自己使用 wordpress.com 提供的 WordPress 系統已經超過十年了,用的還算滿習慣的;但是由於都是使用別人架好的系統,所以其實對於要怎麼架設,並沒有很認真地研究過。

而這篇則是紀錄一下,Heresy 在工作的地方,自己在 Ubuntu Server 上,透過 Docker 架設 WordPress 的紀錄。

首先,這邊參考的是《使用 Docker Compose 架設 WordPress 環境》這篇文章,他的專案放在 GitHub 上(連結)、可以直接使用。

在他的架構下,實際上是透過三個 docker 的容器來建立一個 WordPress 的服務:

  • db:資料庫、使用 mysql:8.0.20
  • wordpress:PHP FPM 服務、使用 wordpress:php7.4-fpm-alpine
  • webserver:網頁伺服器、使用 nginx:latest

其中,有提供對外連線的只有使用 NGINX 來建立的 Web server,其他兩個都只有內部連線而已。

而他的整個服務和 Heresy 比較熟系的 Apache + PHP + MySQL 模式不大一樣,NGINX 提供的 Web Server 和 PHP 並沒有整個綁在一起,而是透過 FPM(FastCGI Process Manager、連結)的模式來做溝通。

這樣的做法據說是速度較快、使用的資源較少(參考);不過老實說,對 Heresy 來說卻也變得更難設定了…


基本使用

總之,Heresy 這邊是還有針對他的設定,做了一些修改,修改用的版本是:https://github.com/KHeresy/wordpress_with_docker_compose

如果要使用的話,基本上就是:

  1. 下載
  2. 修改 ./docker/.env 裡面的 MySQL 帳號密碼
  3. ./nginx/ 下準備 SSL 憑證(檔名是 ssl.csrssl.key
  4. 修改 ./nginx/nginx.conf,將 localhost 改成自己的網域
  5. 進到 ./docker 目錄下,執行 docker-compose up -d

理論上這樣就可以架設一個 WordPress 起來了。之後,只要連上網站,就可以一步一步完成設定了。

其中,如果要自己產生 SSL 憑證的話,可以透過下面的指令來做:

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ssl.key -out ssl.csr 

不過如果是要正式營運的網站的話,最好還是去申請個正是憑證會比較好。


Dockerfile

在 Docker Compose 的部分,設定的檔案是 ./docker/docker-compose.yml,其內容如下(檔案):

version: '3.0'

services:

  heresy_db:
    image: mysql:latest
    container_name: heresy_db
    volumes:
       - ../db_data:/var/lib/mysql
       - ./config/my.cnf:/etc/mysql/my.cnf
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: wordpress
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    networks:
      - wordpress_network

heresy_wordpress:
    depends_on:
      - heresy_db
    image: wordpress:fpm-alpine
    container_name: heresy_wordpress
    volumes:
      - ./config/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
      - ../wordpress:/var/www/html
    restart: always
    environment:
      WORDPRESS_DB_HOST: heresy_db:3306
      WORDPRESS_DB_USER: ${MYSQL_USER}
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
    networks:
      - wordpress_network

  heresy_webserver:
    depends_on:
      - heresy_wordpress
    image: nginx:latest
    container_name: heresy_web
    restart: always
    environment:
      - TZ=Asia/Taipei
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ../logs:/var/log/nginx
      - ../nginx:/etc/nginx/conf.d
      - ../nginx:/etc/nginx/ssl
      - ../wordpress:/var/www/html
    networks:
      - wordpress_network networks:
  wordpress_network:
    driver: bridge

這間使先是稍微修改了容器的名稱,變成:

  • heresy_db:資料庫
    • 會把 ./docker/config/my.cnf 作為 MySQL 的設定檔
    • MySQL 的資料會儲存在產生出來的 ./db_data 下。
  • heresy_wordpressaa:WordPress 系統與 PHP-FPM
    • ./docker/config/upload.ini 是 PHP 的設定檔
    • 會產生一個 ./wordpress 的資料夾,之後網頁的內容都會在這
    • 在內度的網路,透過 3306 port 和資料庫連線
  • heresy_webaa:NGINX 網頁伺服器
    • 對外開放 80 / 443 兩個連接埠
    • ./nginx 這個資料夾下的 .conf 檔(目前只有一個 nginx.conf)會被當作 NGINX 的設定
    • WordPress 產生的 ./wordpress 會以網站跟目錄的形式掛載進來
    • 產生一個 ./logs 資料夾存放存取紀錄

同時,也幫他們使用的網路環境取了一個名字,叫做「wordpress_network」(其實算是非必要的)。

這邊主要是把 MySQL 和 WordPress 的 Docker Image 版本做了修改;另外,他在 WordPress 的 upload.ini 的掛載部分感覺應該是寫錯了,這邊有調整。


NGINX

在 NGINX 的部分,Heresy 也只有在之前弄 Kroki 的逆向代理的時候有玩過一次,所以其實相當不熟…再加上對於 FPM 的設定更是第一次看到,所以其實也弄了好久。

目前的 nginx.conf 這個設定檔的內容則是如下(檔案連結):

log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" '
                   '"$http_x_forwarded_for"'; server {
    listen [::]:80;     listen 80;  
    server_name localhost;     return 301 https://localhost$request_uri; } server {
    listen [::]:443 ssl http2;     listen 443 ssl http2;  
    server_name  localhost;     ssl_certificate /etc/nginx/ssl/ssl.csr;     ssl_certificate_key /etc/nginx/ssl/ssl.key;  
    root /var/www/html;     index index.php;  
    access_log /var/log/nginx/access.log custom;     error_log /var/log/nginx/error.log;     client_max_body_size 100M;  
    location ~ /wp-admin/.*\.(js|css|svg|gif|jpg|png) {
        allow 127.0.0.1;
        deny all;
        try_files $uri =404;
    }
 

    location ~ /(wp-admin|wp-login\.php) {
        allow 127.0.0.1;
        deny all;
 
        try_files $uri $uri/ /index.php?q=$uri&$args;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass heresy_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 / {
        try_files $uri $uri/ /index.php?$args;     }
 
    location ~ \.php$ {
        try_files $uri =404;         fastcgi_split_path_info ^(.+\.php)(/.+)$;         fastcgi_pass heresy_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;     } }

這邊會去修改 NGINX 的設定檔的原因,主要是想透過限制只有特定 IP 可以存取後台,來加強系統的安全性,實際上加入的是紅字和藍字的部分。

紅字的部分主要的目的是為了保護安全,所以想把 /wp-admin 這個後臺的網址、以及 /wp-login./php 這個登入的網址擋掉、只允許特定的 IP 存取(這邊是僅允許 127.0.0.1,有需要請自行修改);而由於這邊都是 PHP 的網頁,所以還是得加入 fastcgi 相關的設定。

本來以為單純加入一個條件就可以了,結果沒想到這樣的設定雖然可以處理 PHP 的檔案,但是其他像是 .js.css.svg 這類的靜態檔案,卻似乎會因為 Fast CGI 的關係會變得沒辦法正確處理。而個人試出來的解決方法,好像就只能針對這些非 PHP 的檔案,另外再加入一個條件(藍字)了。

理論上,這邊應該還會有更好的處理方法,不過目前算是勉強可以動了。


碰到的問題

雖然說基本上這樣是可以成功架起來了,不過在這過程還是有碰到一些問題。

其中一個,是在某些電腦上,會碰到在「網站狀態」裡面回報「REST API 發生錯誤」的狀況。

雖然依舊還是可以運作,但是在有安裝部分外掛(例如 WP Statistics)的情況下,就可能會導致網站速度大幅降低。

這個問題在換到乾淨的 VM 上就沒有發生了,所以目前認定應該是和主機、或是 Docker 的設定有關;但是目前還不知道該如何修正。

另外,就是當有大量操作的時候(匯入資料、或是多次批次修改),似乎很容易會讓 WordPress 的容器整個當掉,導致後續的要求都變成 504 Gateway Timeout;而如果出現這個狀況,最快的解決方法似乎就是重啟 WordPress 的容器了。

這個問題應該是使用 NGINX + PHP-FPM 的人都有機會碰到的,一般建議的方法就是去限制最常執行時間(參考《解決 Nginx 與 php-fpm 發生 504 Gateway Time-out 問題》);不過 Heresy 目前還沒認真處理這個問題就是了。


資料備份

而都弄完之後,理論上要備份的內容會是:

  • /db_data:MySQL 的資料庫檔案。
    • 技術上在停機的狀況下應該是可以備份整個資料夾,但是實際上應該還是用資料庫備份工具(例如 mysqldump)來做會更好。
  • /wordpress/wp-content:WordPress 的檔案資料
    • WordPress 的主題、外掛、或是使用者上傳的多媒體檔案都會在這邊;理論上 WordPress 非文字的資料都在這,只要備份這整個資料夾就可以了。

至於要怎麼做定時自動備份、之後就還要再來玩看看了。


目前玩起來…恩,WordPress.org 提供的 5.8.2 版感覺上和 WordPress.com 提供的版本有相當的差異,尤其是後台的部分,感覺上比 WordPress.com 的版本舊很多。

而很多 Heresy 本來以為會內建的功能(統計),實際上也都得靠外掛才能做到;所以實際上,真的架設好了,其實才是麻煩的開始啊~(苦笑

對「自行透過 Docker 建立 WordPress 網站」的想法

  1. 現在的Apache+PHP+MySQL和用NGINX的方法一樣,都是通過PHP-FPM調用PHP的,因爲基於libphp的 Apache MPM prefork 性能爛得要死。
    現在Apache和NGINX的用法區別不大,NGINX不支持.htaccess所以一大堆你需要寫到NGINX配置文件裏的東西。

      • 全世界跟他們熟的人都不多,大多數人甚至是業內人也都是調通了就不管了。
        我當初爲了避免遇到這種問題,專門寫了個docker-compose項目在github上,幾年了,目前只有1star,然後除了我自己的網站和我兼職的項目之外,據我所知目前沒有其他人用。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.