使用 Docker, WordPress, PHP 7.3, WP-Cli, MariaDB, Redis, Nginx, SSL (Let's Encrypt) 搭建多個獨立網站的開發環境與正式環境。
啟用多個 WordPress 和 非 WordPress 網站容器,再讓它們共用一個 DB 容器。另外還可搭配 Redis、MailCatcher、WP-Cli 等容器服務。
請注意,本 Repo 需要先使用:WP Proxy Companion (https://github.com/mrmu/wp-proxy-companion) 建立 Nginx Proxy 之後,才能正常使用。
無論本機或正式環境:
cd /var/docker-www
git clone https://github.com/mrmu/wp-proxy-sites.git
sudo cp sample.env .env
無論本機或正式環境:
127.0.0.1 wp1.test
127.0.0.1 wp2.test
127.0.0.1 phpweb.test
開始設定 WP 網站容器,將 docker-compose.sample.yml 另存為 docker-compose.yml:
sudo cp docker-compose.sample.yml docker-compose.yml
再打開 docker-compose.yml 修改。範例中對應的容器是 wp1,可以修改的部份:
啟用本repo的 docker-compose.yml,在 wp-proxy-sites/ 下執行:
docker-compose up -d --build
若是第一次使用,建議你docker-compose up 不要加-d,可以觀察一下執行過程中有沒有發生問題,只要 Ctrl+c 就能離開,再下 docker-compose down 關掉所有 container,就可以重新下 up 指令。(註:docker-compose down 和 up 都要在 .yml 同目錄下執行才能針對該設定生效)
第一次啟用時間會比較長,因為要下載各個 docker image 並啟用。
跑完若一切正常,執行 docker ps -a 就會看到所有運行起來的容器了。而此時在瀏覽器輸入網址,就能看到 wp 的安裝畫面了。
之後要再增加其他容器 (比如網站容器),只要再編修 docker-compose.yml 存檔後,再啟用該容器即可,要怎麼增加其他容器的設定可以參考下面的說明。
db: 定義一個資料庫容器(mariadb),這會讓後面 3 個網站容器共用。db 容器是一定要存在的,其他的容器則是依使用狀況增減修改。
wp1: 定義一個官方的 WordPress 容器 (本身自帶 apache 和 php),是故意寫的比較像正式環境的設定,所以會使用到 db 和 redis 這兩個容器的服務。它定義了:
VIRTUAL_HOST: wp1.test,表示會讓佔用 80 /443 port的 wp proxy companion 以 Nginx 的反向代理設定導至此 wp1 容器的 apache。
LETSENCRYPT_HOST 及 LETSENCRYPT_EMAIL: 這會讓 wp proxy companion 幫忙申請 Let’s encrypt 憑證並以 docker-gen 產生 nginx 反向代理的設定,再自動套用,但網域必須是真正指向主機IP的,所以本機測試不會成功。(請先讓 http 版本網站上線,再設定這兩項,才能正確通過 challenge 取得憑證,請參考 wp proxy companion 的說明)
redis: 做為 redis server 的容器。wp1 要使用 redis,還須要額外安裝 Redis Object Cache 這個 WP 外掛,要設定連結的 redis host,就寫 redis 的 container name 即可 (本repo裡的設定就叫 redis)。
wp2: 一樣是定義一個官方的 WordPress 容器,這邊故意寫的比較像本機的設定,會使用到 db 和 mailcatcher。這個容器就只定義了 VIRTUAL_HOST。
cli-for-wp2: 定義一個 wp-cli 容器指定給 wp2 使用。使用方式如下:
下指令進入cli的bash:
docker-compose run --rm cli-for-wp2 bash
這樣就會進入wp目錄,並且可以下wp-cli 指令。
phpweb: 這裡定義了第三個網站容器,但它不是 wp,就只是一般的 php+apache。它的 volumn 是對應到本機的 ./app/sites/phpweb,所以如果這裡沒有東西,瀏覽 phpweb.test 會出現 Forbidden。
mailcatcher: 主要用於開發環境,這個容器會幫忙攔下網站發出的信件,只要用瀏覽器開 1080 port 就可以看見web mail 的介面,裡頭就會有信件,對於測試信件的情境 (不讓它真的被寄出) 很方便。
最後定義了一個外部的 docker network 叫 wp-proxy,也就是與 wp proxy companion 連線的設定。
這裡有些設定範例,可以參考寫法。
dockerfile-sample/php7.3:如果要安裝純 PHP 環境,但想自行安裝 Ubuntu 套件或啟用 Apache module,可參考這個目錄下的 dockerfile,它額外安裝了 mysqli、pdo、pdo_mysql 並且啟用 apache rewrite module,剛好可以作為 Laravel 開發使用。
dockerfile-sample/wp5.3-xsl:如果要安裝 WP 環境,但想自行安裝 Ubuntu 套件,可參考這個目錄下的 dockerfile,它額外安裝了 xsl 套件,比如要安裝 Google XML sitemap 的外掛,就需要 ubuntu 有 xsl 套件。
完成自訂的 Dockerfile 後,可於 docker-compose.yml 裡使用「build:」來取代原來的「image:」設定。如使用「build: ./dockerfile-sample/php7.3」取代掉 「image: ‘php:7.3-apache’」。(但請另建目錄,不要直接使用 dockerfile-sample/)
```
extra_hosts:
members.xxx.xx: 10.1.4.xxx
dev.members.xxx.xx: 10.1.4.xxx
```
關於改變 php.ini 的設定部份有兩種方式:
修改好要 docker-compose down 再 docker-compose up -d —build 讓它套用設定。
file_uploads = On
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600
php_value post_max_size 64M
php_value upload_max_filesize 64M
php_value max_execution_time 600
php_value memory_limit 256M
要分開管理開發環境及正式環境的 docker-compose.yml 設定,可依據用途建立多個 yml 檔,不會更動到的設定就放在 docker-compose.yml,假設我習慣在本機的容器設定不同,就把相關設定移到 docker-compose.local.yml;正式環境的設定就移動到 docker-compose.prod.yml。
若是在本機環境要執行 docker-compose up,就可以這樣下指令:
docker-compose -f docker-compose.yml -f docker-compose.local.yml up -d
docker down 也是比照辦理:
docker-compose -f docker-compose.yml -f docker-compose.local.yml down
如果更新或新增了 docker-compose.yml (或 prod.yml, local.yml 都一樣) 裡的容器服務設定,但不要整個全部 down 再 up (Downtime 時間長),可下指令 (以本機為例):
docker-compose -f docker-compose.yml -f docker-compose.local.yml up -d --no-deps --build 容器名稱
如果要加入 www to non-www 的設定,可以在 VIRTUAL_HOST 加入 www 的設定,如:
VIRTUAL_HOST: audilu.com, www.audilu.com
如此 nginx-proxy 就會多生出一組設定。
要變更現有WP容器的PHP版本,可以修改 Image 來源,比如 wordpress:5.2.2-php7.3 改為 wordpress:5.0.1-php5.6,再重啟容器即可生效,WP 目錄下的檔案都不會更動。也因為 WP 目錄下的檔案都不會更動到,所以 wp 版本不會因此降到 5.0.1,除非是第一次運行,才會下載 WP 5.0.1 的檔案。
WP 底下目錄和檔案的權限設定,以目錄 755 及檔案 644 為建議 (官方建議在此),指令如下:
sudo find ./目標目錄 -type d -print0 | xargs -0 sudo chmod 0755
sudo find ./目標目錄 -type f -print0 | xargs -0 sudo chmod 0644
或
sudo find ./目標目錄 -type d -exec chmod 0755 {} \;
sudo find ./目標目錄 -type f -exec chmod 0644 {} \;
PHP Composer:可以在容器外使用,也可以啟用一個 composer 容器,就像 docker-compose.yml 範例裡註解的一樣,要執行它可取消註解,並且下指令 (這樣做沒有比較方便,所以用習慣的方式就好XD):
docker-compose run wp2-composer update
Git:因為網站目錄已透過 volumn 設定 mapping 到容器外部了,所以只要在外部使用 Git 即可。
Node.js:會用到 Node.js 通常是前端需要套件管理工具,如:Webpack, Gulp …等,因為佈景目錄已透過 volumn 設定 mapping 到容器外部,所以在外部執行即可。
docker ps -a
docker restart [容器ID]
docker stop [容器ID]
docker rm [容器ID]
docker-compose stop
docker-compose down
docker-compose up -d --force-recreate
docker network ls
docker exec db容器ID env
docker exec -it db容器ID mysql -uroot -p
docker container top 容器ID
docker logs 容器ID -f 1>/dev/null
docker logs 容器ID -f 2>/dev/null
執行 db 容器內的 mysqldump 將資料倒到 .sql (配合utf8mb4語系)
docker exec -it db /usr/bin/mysqldump --default-character-set=utf8mb4 --hex-blob -u root -p{root_password} {database_name} > backup.sql
將 .sql 還原至 db 容器內的 mysql
docker exec -i db /usr/bin/mysql -u root -p{root_password} {database_name} < backup.sql
到這裡,新的網站目錄 (/wp-proxy-sites/sites/新站/) 和全新的WP檔案會被建立,對應的資料庫也會被建立 (但還是空的,因為還沒跑安裝)。好奇的話也可以看一下 nginx proxy 設定 (wp-proxy-companion/nginx/conf.d/default) 也都準備好指到網站容器裡的 Apache 了,
docker-compose up -d --no-deps --build 網站容器名稱
到這裡,等個5~30秒 (也可以查看一下 wp-proxy-letsencrypt 容器的 log,看它有沒有在運作,若等不及可以 restart 它,讓它重跑檢查),檢查 /wp-proxy-companion/nginx/certs 目錄下有沒有對應網域的憑證檔,若有的話,就表示憑證已安裝成功了。
docker-compose up -d --no-deps --build 網站容器名稱
docker images
docker rmi {image名字}
WARNING: The MYSQL_ROOT_PASSWORD variable is not set. Defaulting to a blank string.
WARNING: The MYSQL_DATABASE variable is not set. Defaulting to a blank string.
ps -auxwf -f | grep mysql // 尋找 mysql行程
kill -9 {mysql的PID} // 刪除 mysql