Docker + WordPress

好耐冇跟進過 Docker,今次想整合一下手頭上用 WordPress 做嘅 websites,意思係用一部 Docker 裝哂啲 WordPress websites 入去,以後如果要開新嘅 WordPress website 就可以用 Docker containers 複製一下就用得,唔使一個 website 一個 VM,有好處亦有唔好處,不過唔諗得咁多,用落就知麻煩多呀定係麻煩少咗。

1. 首先起隻 VM,安裝隻 Ubuntu 18.04 LTS

我用 4 vCPU + 4GB RAM + 256GB Storage,ubuntu 淨係要 core 加埋 open-ssh-server。唔…如果你隻 ubuntu boot 咗之後成日出啲

IO Error dev fd0 sector 0

你可以根據下面幾行 commands 叫佢收聲:

echo "blacklist floppy" | sudo tee /etc/modprobe.d/blacklist-floppy.conf
sudo rmmod floppy
sudo dpkg-reconfigure initramfs-tools

仲有,要 set 番啱你部 VM 個 TimeZone,如果唔係都幾麻煩㗎。

2. 裝 Docker 前傳:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-cache policy docker-ce

解釋一下:

#1 同 #2 係更新 ubuntu

#3 係加入啲當使用 HTTPS 時要用到嘅「証書」

#4 加入 Docker 官方嘅 GPG key,唔好漏咗最後嘅 dash

#5 就係加入 Docker 官方檔案嘅下載路徑,我用咗 stable ,如果你係用 ubuntu 19.04 嘅話,目前冇 stable 你要用 test 測試版

#6 係 check 下目前可以下載嘅 Docker 版本

Screen Cap:

你會見到 docker-ce Installed: (none) 即係部機目前未有安裝 Docker。𠵱,點解叫 docker-ce?係呀,Docker CE 即係 Community Edition 佢有另外一個收費版叫 EE (Enterprise Edition),我哋冇錢咪用 docker-ce 囉!

3. 安裝隻 Docker

sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo systemctl status docker

#1 係安裝,#2 係顯示隻 Docker 係咪正常運作中:

如果出到上圖,即係運作正常!

4. 後傳,裝 docker-compose

係強勁嘅 docker 工具,一陣安裝 WordPress 時要用到:

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

#1 係下載啲 scripts,存入指定嘅位置

#2 係改一下隻檔案號屬性,等佢可以 execute

#3 就係執行一下,叫佢顯示佢個版本號碼以証明安裝正常

目前係 v1.23.1

5. 整定個 Swap File

Swap File 可以避免日後運作嘅時候隻 MariaDB 或者 mySQL 食爆啲 memory:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo cp /etc/fstab /etc/fstab.bak
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

我俾 1G 做 swap file size,應該夠用,我打算放 10~20 隻 websites 喺喱隻 docker 上面。有咁好生意?😂

6. 修改 login user 權限

經常要執行 Docker commands,而每次都要加 sudo 喺前面,有啲麻煩,如果做咗喱一步,咁以後就唔使一定要加 sudo,係咪成個人舒服哂呢? Optional 嘅,不過啱我喱種「懶人」!

sudo groupadd docker
sudo usermod -aG docker $USER

真正嚟講,你個權限冇變到,而係將你加入埋 docker group 入面。

7. 第一隻 Container — Portainer

Docker 嘅管理一般係經 SSH 用 docker commands 操作, 有時會冇咁方便,Portainer 係一隻 web browser based 嘅 Docker GUI,唔係最強大嗰隻,不過夠哂我用。

docker volume create portainer_data
docker run -d -p 9000:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

#1 建立一隻 docker volume,係喺隻 ubuntu 入面割一塊地方用嚟放 portainer data,docker 嘅術語係 persist 啲 data,即係 portainer 運作嘅時候產生嘅 data 放哂喺喱度,當隻 Portainer 唔見咗嘅時候(有人刪除咗隻 portainer container),啲 data 仲喺度,直到刪除埋隻 volume。

#2 係創建一個新嘅 container,咁樣難啲介紹,改成咁:

docker volume create portainer_data
docker run -d \
  -p 9000:9000 \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer

用咗分段,#2 係叫 docker 建立一隻新嘅 container,#3 係 port-forward 將外面嘅 port 9000 引入執內聯網嘅 port 9000,外網可以唔一定用 9000,不過冇做嘅話你喺外面就 access 唔倒隻 Portainer,#4 叫佢部機 reboot 之後都再 load 過隻 container,#5 #6 係將外面嘅預設 volume folder 聯到內網,#7 係話隻 container 個 image 係咩東西,於是,docker 會 check 下 local 有冇喱隻 image,冇就會上網下載。

用得:

喺 chrome 去 IP#:9000,初次登入可以設定用戶名同密碼:

next, 要選 local,因為隻 Portainer 同隻 docker 喺同一部機:

next, Dashboard 顯示隻 docker 有 3 個 networks、1 隻 container、1 隻 image、1 隻 volume:

點解有 3 隻 networks?係 docker 嘅 defaults,分別係:

個 post 已經好長,啲 screen cap 唔放喇,自己安裝段自己去睇啦。

8. 戲肉,安裝 WordPress

其實係包含咗 3 隻 containers,1 隻係 WordPress web server,1 隻係 MariaDB SQL serve,1 隻係 phpmyadmin web sql admin (optional,唔裝都冇問題嘅)。一次搞掂哂就要出動 docker-compose 了!

先去位大師嗰度下載位大師寫嘅 scripts,網址。位大師會用埋 nginx 做 reverse-proxy(唔使搞 port-forward),仲加埋 Let’s Encrypt 認證,一部機一隻 docker 搞哂,由於我已經有 reverse-proxy 同 Let’s Encrypt 喱兩個部份,所以我要修改下啲 scripts,而且,位大師有啲嘢冇做,留番俾細嘅自己搞,我又要改下個 script 去搞埋先算最理想嘅 script,於是乎就變成咁:

8.1 用 Visual Studio Code 做 editor,wp_paulus 係我 copy wordpress_01 嘅:

8.2 將個 sample.env 改名為 .env,內容亦要改:

 

DB_CONTAINER=mariadb_paulus
DB_NAME=db_paulus
DB_USER=wordpress
DB_PASSWORD=XXXXXXXXXXX
WP_CONTAINER=wp_paulus
WP_TABLE_PREFIX=wp
WP_THEME=custom-theme
WP_PLUGIN=custom-plugin
VIRTUAL_HOST=paulus.nxstudio.com
VIRTUAL_PORT=8001
LETSENCRYPT_EMAIL=support@nxstudio.com
COMPOSER_CONTAINER=cp_paulus
PMA_CONTAINER=pma_paulus
PMA_VIRTUAL_PORT=1001
PMA_ROOT_PASSWORD=XXXXXXXXXXX

好難解釋咁多,自己去睇。😎

8.2 加一個檔案,叫做 uploads.ini,內容係:

file_uploads = On
memory_limit = 256M
upload_max_filesize = 256M
post_max_size = 256M
max_execution_time = 600

我隻 WordPress 准上傳檔案 size 最大係 256MB

8.3 修改隻 docker-compose.yml 檔案:

version: '3'

services:

  db:
    container_name: $DB_CONTAINER
    image: mariadb:latest
    restart: always
    volumes:
      - /srv/www/${VIRTUAL_HOST}/db_data:/var/lib/mysql
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: 1
      MYSQL_DATABASE: $DB_NAME
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD

  wp:
    container_name: $WP_CONTAINER
    build: .
    depends_on:
      - db
      - cp
    restart: always
    volumes:
      - ./theme:/var/www/html/wp-content/themes/${WP_THEME}:rw
      - ./plugin:/var/www/html/wp-content/plugins/${WP_PLUGIN}:rw
      - /srv/www/${VIRTUAL_HOST}/wp_content:/var/www/html/wp-content:rw
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    environment:
      WORDPRESS_DB_HOST: $DB_CONTAINER
      WORDPRESS_DB_NAME: $DB_NAME
      WORDPRESS_DB_USER: $DB_USER
      WORDPRESS_DB_PASSWORD: $DB_PASSWORD
      WORDPRESS_TABLE_PREFIX: $WP_TABLE_PREFIX
      VIRTUAL_HOST: $VIRTUAL_HOST
      VIRTUAL_PORT: $VIRTUAL_PORT
      #LETSENCRYPT_HOST: $VIRTUAL_HOST
      #LETSENCRYPT_EMAIL: $LETSENCRYPT_EMAIL
      #LETSENCRYPT_TEST: 'true'
    ports:
      - ${VIRTUAL_PORT}:80

  # phpMyAdmin is optional
  pma:
    container_name: $PMA_CONTAINER
    image: phpmyadmin/phpmyadmin
    depends_on:
      - db
    restart: always
    ports:
      - ${PMA_VIRTUAL_PORT}:80
    environment:
      PMA_HOST: $DB_CONTAINER
      MYSQL_ROOT_PASSWORD: $PMA_ROOT_PASSWORD
  cp:
    build: composer
    container_name: ${COMPOSER_CONTAINER}
    volumes:
      - /srv/www/${VIRTUAL_HOST}/wp_content:/app/wp-content
    command: composer install

#networks:
#  default:
#    external:
#      name: nginx_proxy

講下改咗咩:

#28 我加嘅,叫佢將 8.2 準備咗嘅 uploads.ini 抄入去做 php 嘅 config 檔案之一

#37 #38 我 comment out 咗,因為我唔用佢嘅 LetsEncrypt

#40 #41 我加嘅,因為我唔用佢嘅 reverse-proxy 所以要做 port-forward

#43~#54 我加嘅,叫佢安裝隻 phpmyadmin,注意,如果你唔用但係又想用其他軟件去 access 個 database,你就要喺 db 入面加番 port-forward 嘅資料。

#62~#65 係我 comment out 嘅,我唔用隻 nginx 就唔使搞多一隻 network

係以上咁多啫,冇其他嘢要加要改!

8.4 用 WinSCP 經 SSH 傳去隻 docker 度:

跳入啱嗰上傳嘅檔案夾:

8.5 進行安裝:

輸入

docker-compose up -d

走咗一大輪之後就會出現 4 個 done:

最重要嘅收尾:

docker exec wp_paulus chown -R www-data:www-data wp-content

准隻 WordPress 上傳檔案同埋可以更新啲 themes/ plugins

9. 確認安裝結果

9.1 Dashboard 顯示結果:

9.2 Container List:

多咗 3 隻 live 嘅 containers 同埋一隻完成使命嘅 cp_paulus,請留意 3 隻 live containers 都係用 127.18.0.x subnet,即係話,佢哋 3 位自成一角,其他人要 access 佢哋就要經指定嘅渠道先得。

9,3 Image List:

擁有私人嘅 images

9.4 Network List:

擁有私人嘅 network 添

9.5 Volume List:

私人嘅 storage 用嚟 persist 自己嘅 data

9.6 起動 WordPress:

用 Chrome 輸入 #IP:8001

WordPress 人,你識得點執手尾啦,係唔係?

9.7 睇埋隻 phpmyadmin:

用 Chrome 去 #IP:1001

順利登入

10 Clone 多一隻 WordPress

Copy & Paste wp_paulus 然後淨係改個 .env 檔案就掂哂!

clone 咗一隻叫 wp_arron 嘅,經 WinSCP 上傳去隻 docker 度,然後 cd 入去 wp_arron,然後 docker-compose up -d,收工。