【低成本家用伺服器】之三 – 10分鐘在Raspberry Pi上架多個WordPress網站

這篇文章中,我將介紹如何在 Raspberry Pi 上使用 Docker 和 docker-compose 設置多個 WordPress 網站。這篇文章將只討論設定方式和基本概念,我們假設你已經有了自己準備使用的網域名稱,並且你的環境中Raspberry Pi已經有了對外連線和接受外來連線的設定,包括防火牆設定、分享器設定等將不在討論範圍內。

在 Raspberry pi 上安裝 docker 和 docker-compose

為求簡單,我們會利用Docker和docker-compose來部署我們的網站和需要的支援。因此,我們會從安裝Docker和docker-compose開始。

什麼是Docker?

Docker 是一個用於開發和運行應用程式的開放平台。原本的主要用途是可以更方便的解決開發環境和部署環境不一致的問題。使用Docker讓我們將應用程式與其所有依賴關係打包到一個稱為「容器」的單位中。這些容器可以在任何地方運行,這意味著你可以在本地機器上進行開發和測試,然後在各種雲端環境、虛擬機或裸機上進行部署,而無需進行任何修改。

由於Docker的使用非常方便且容器相對傳統的虛擬機輕量,現在許多熟悉這個環境的非開發者也經常將它使用在教學或部署工具的情境當中,類似於虛擬機的用法。

什麼是docker-compose?

docker-compose 是 Docker 的一個工具,用於定義和運行多個 Docker 容器。它允許用戶使用 docker-compose.yml 文件來配置應用程式的所有服務,然後只使用一個命令就能啟動所有的服務。

像是在常見的部署網站情境中,這個檔案可能包括一個 Web 伺服器、一個資料庫和一個緩存,那麼使用 docker-compose,您可以在一個 docker-compose.yml 文件中定義所有這些服務,並確保它們在相同的網絡中運行,共享存儲之類。不但容易管理也容易複用。

Docker和docker-compose的安裝步驟

以下列出安裝步驟,這些步驟在裝有 Ubuntu server 20.04 的 Raspberry Pi 4上測試確認過。首先我們安裝Docker:

curl -sSL https://get.docker.com | sh
sudo usermod -aG docker ubuntu

接下來重開機,之後再執行以下指令安裝docker-compose:

sudo apt-get install -y libffi-dev libssl-dev
sudo apt-get install -y python3 python3-pip
sudo apt-get remove python-configparser
sudo pip3 -v install docker-compose

設定 nginx-proxy 和 LetsEncrypt

為了支援多個 WordPress 網站,我們在啟動Wordpress容器之前,還需要先設定另外兩個容器,nginx-proxy和LetsEncrypt。

什麼是nginx-proxy?

nginx-proxy是一個反向代理伺服器。反向代理的功能有許多,因為我們不是要討論網站技術,這裡只提供一個直覺的說明。nginx-proxy在我們今天這個環境中所擔任的角色就類似總機小姐,當電話 (一個網頁要求) 打進來的時候它會幫我們將電話轉接到正確的地方。有了它,我們就能夠在同一台Raspberry Pi機器上同時使用多個Wordpress容器。nginx-proxy容器將會負責幫我們把網頁要求轉接給正確的Wordpress容器。

什麼是LetsEncrypt?

LetsEncrypt在這裡的主要功能是讓我們的網站可以支援https。

有在上網的人大概都看過網址前面的https吧?這裡s的意思就是這是一種安全的網頁協定。想像你正在進行一場私人對話。你可能希望確保只有你和另一個人知道這次對話的內容,而旁觀者無法聽到或理解。這就是網站與其使用者之間的通信安全所要做的事情,https就是這種技術,並且在實現時使用了一種名為 “SSL/TLS” 的技術來確保這種安全。

要使這種安全通信成為可能,你需要一個叫做 “SSL證書” 的東西。這就像一個官方的身分證明,確認你是誰你所說的自己是。而 “Let’s Encrypt” 就是一個提供這些證書的機構。Let’s Encrypt提供完全免費的SSL證書,特別適合我們省成本的伺服器使用。我們接下來要設定的LetsEncrypt容器,就會幫我們處理獲得SSL證書的流程。

設定步驟

設定Docker網路

首先我們需要創建一個所有容器之間溝通使用的Docker網路。這只需要做一次。稍後我們的Wordpress網站容器也將透過這個網絡與反向代理進行通信。

docker network create --driver bridge nginx-proxy

設定nginx-proxy和letsencrypt-nginx-proxy-companion容器

我們要使用 nginx-proxy 和 letsencrypt-nginx-proxy-companion 來處理以上提到的兩個容器。首先為nginx-proxy反向代理服務創建一個資料夾:

mkdir nginx-proxy
cd nginx-proxy

接下來在這個資料夾下,創建一個 docker-compose.yml:

version: "3"
services:
  nginx-proxy:
    image: alexanderkrause/rpi-nginx-proxy
    container_name: nginx-proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf:/etc/nginx/conf.d
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"

  letsencrypt:
    image: alexanderkrause/rpi-letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-le
    restart: always
    depends_on:
      - nginx-proxy
    volumes:
      - ./conf:/etc/nginx/conf.d
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro

networks:
  default:
    external:
      name: nginx-proxy

Docker 的優點是我們可以輕鬆啟動容器。不過對於不同的的raspberry pi系統,我們有時需要找到適用於 ARM 處理器架構的正確映像才能執行。以上的docker-compose.yml實測可以同時在安裝了Raspbian和Ubuntu上運行。這裡使用的 alexanderkrause 版本映像是基於 jwilder/nginx-proxy 進行調整的。Jason Wilder 的詳細帖子可以在這裡找到。使用它之前,我們還需要 jwilder 創建的 nginx.tmpl。

curl -o nginx.tmpl https://raw.githubusercontent.com/jwilder/docker-gen/master/templates/nginx.tmpl

簡而言之,rpi-nginx-proxy 是反向代理,rpi-letsencrypt-nginx-proxy-companion 會檢測並自動幫助我們從 letsencrypt 獲取證書,這樣我們稍後為每個 wordpress 網站設置的所有網址都將支持 https。

接下來將設定好的反向代理用docker-compose啟動:

docker-compose up -d

使用 docker-compose 設置多個 WordPress 部落格!

接下來終於可以設置我們的 WordPress 網站了。我們持續使用 docker 使這件事情比較輕鬆。首先我們會為每個網站創建了一個目錄。如果你只想設定一個網站的話,也可以只創建一個資料夾就好。

mkdir wordpress-<sitename>
cd wordpress-<sitename>

每個網站會有一個自己的資料夾,在每個資料夾中,為這個網站創建一個名為docker-compose.yml的檔案:

version: '3.3'

services:
   db:
     container_name: db-<sitename>
     image: hypriot/rpi-mysql
     volumes:
       - ./db_data:/var/lib/mysql
       - ./home/db:/home/db
       - ./sqldump:/sqldump
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     container_name: wordpress-<sitename>
     depends_on:
       - db
     image: wordpress:latest
     expose:
       - 80
     restart: always
     volumes:
       - ./data_volume:/var/www/html
       - ./home/wp:/home/wp
     environment:
       VIRTUAL_HOST: <YOUR_SITE_URL>
       LETSENCRYPT_HOST: <YOUR_SITE_URL>
       LETSENCRYPT_EMAIL: <YOUR_EMAIL>
       WORDPRESS_DB_HOST: db_<sitename>:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
     links:
       - db:db_<sitename>

networks:
  default:
    external:
      name: nginx-proxy

請注意上面的<sitename>、<YOUR_SITE_URL>、<YOUR_EMAIL>都需要自己定義。每個網站的相關容器要有自己的conatiner_name確保沒有衝突。這將確保 wordpress 容器始終找到正確的 db 進行數據請求。否則,當您運行多個這些容器時,由於複製了服務名稱,可能會導致連接混亂。

測試它!

現在我們的配置已經完成。對於每個網站,nginx-proxy 會自動檢測它們通過我們設置的 nginx-proxy 網絡啟動。然後 letsencrypt companion將查看我們為每個網站配置的主機名稱和電子郵件,並為我們拉取證書。

最後,我們啟動每個網站的實例。在網站的每個目錄中,執行:

docker-compose up -d

太棒了!執行時letsencrypt companion需要一些時間來完成拉取證書的工作,所以啟動後可能要等幾分鐘,但幾分鐘後應該就能夠使用 https://<your_site_url> 地址訪問所有網站。

系列文章


謝謝你看完這篇文章。如果你喜歡我的文章,請追蹤Facebook粉專TwitterIG

發表迴響取消回覆