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。
如果要使用的話,基本上就是:
- 下載
- 修改 ./docker/.env 裡面的 MySQL 帳號密碼
- 在 ./nginx/ 下準備 SSL 憑證(檔名是 ssl.csr 和 ssl.key)
- 修改 ./nginx/nginx.conf,將 localhost 改成自己的網域
- 進到 ./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_networkheresy_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_networkheresy_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 本來以為會內建的功能(統計),實際上也都得靠外掛才能做到;所以實際上,真的架設好了,其實才是麻煩的開始啊~(苦笑