跳至主要内容

6.5 範例一二三

本小節完全屬於練習的章節,會有兩個題目讓大家多多熟悉 Docker Compose 的使用。

透過 Docker Compose 建立 Drupal 練習

每一個章節都會提供一些小小的練習來熟悉本章的內容,通常會比較難一點;若是想不出來也不需要灰心,有些時候可能是指令不熟悉導致,可以往前翻閱來加強記憶喔,亦或是翻到後面的解答章節也可以幫助你解惑喔,記得 --help 以及 docs.docker.com 會是你最好的夥伴。

這個練習的目的就單純的希望大家可以自己手動寫一次 docker-compose.yml,我自己也很常在學習新事物的時候,看了都會,寫了卻不會的狀況,所以即使我們前面介紹了這麼多的 docker-compose.yml,沒有真的寫過還是沒辦法驗證自己真的懂了。

而這次任務的目的是建立一個名為 Drupal 的內容管理系統 ( 就像是 WordPress ) 搭配 PostgreSQL 做為資料庫來儲存資料。

  1. 使用 drupal 以及 postgres:14-alpine 兩個映像檔作為 service
  2. drupal 這個服務的 port 打開到 8080,這樣您可以透過 http://localhost:8080 來進入服務
  3. 要記得 postgres 映像檔啟動時需要 POSTGRES_PASSWORD、POSTGRES_DB、POSTGRES_USER 這些環境變數,不要忘了用 Volume 來儲存資料。
  4. 閱讀 Drupal 在 DockerHub 的說明,並且用 Volume 來儲存 Drupal 的設定、外觀、模組等等。
  5. 進入 https://localhost:8080 並完成 Drupal 的設定,且重新啟動確認所有的 Volume 皆有作用。

小提示: Drupal 預設的資料庫 DNS 是 localhost,但記得在 Docker 虛擬網路世界中,是透過容器的名字來當作 DNS 喲!

透過 Docker Compose 建立 Drupal 練習解答

答案可以在本書的 GitHub 儲存庫中 ch-06 內的docker-compose-drupal-answer 可以找到。

  1. 首先是使用 drupal 以及 postgres 當作服務,所以可以先把 docker-compose.yml 寫成這樣。
version: '3.9'

services:
drupal:
image: drupal:latest
container_name: drupal

database:
image: postgres:14-alpine
container_name: database
  1. 把 drupal 這個服務的 port 打開到 8080
version: '3.9'

services:
drupal:
image: drupal:latest
container_name: drupal
ports:
- 8080:80

database:
image: postgres:14-alpine
container_name: database
  1. 要記得 postgres 映像檔啟動時需要 POSTGRES_PASSWORD、POSTGRES_DB、POSTGRES_USER 這些環境變數,不要忘了用 Volume 來儲存資料。

這邊的資料庫相關設定一樣採用前面有提過的 .env 來注入環境變數,忘記的人可以往前翻閱。

version: '3.9'

services:
drupal:
image: drupal:latest
container_name: drupal
ports:
- 8080:80

database:
image: postgres:14-alpine
container_name: database
enviroment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- database:/var/lib/postgresql/data

volumes:
database:
  1. 閱讀 Drupal 在 DockerHub 的說明,並且用 Volume 來儲存 Drupal 的設定、外觀、模組等等。

Drupal DockerHub Volume 說明

version: '3.9'

services:
drupal:
image: drupal:latest
container_name: drupal
ports:
- 8080:80
volumes:
- drupal-modules:/var/www/html/modules
- drupal-profiles:/var/www/html/profiles
- drupal-sites:/var/www/html/sites
- drupal-themes:/var/www/html/themes

database:
image: postgres:14-alpine
container_name: database
enviroment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- database:/var/lib/postgresql/data

volumes:
drupal-modules:
drupal-profiles:
drupal-sites:
drupal-themes:
database:
  1. 進入 https://localhost:8080 並完成 Drupal 的設定,且重新啟動確認所有的 Volume 皆有作用。

根據前面的步驟都把 docker-compose.yml 寫好後,就可以來一鍵啟動了。

$ docker compose up --detach
[+] Running 8/8
⠿ Network docker-compose-drupal-practice_default...
⠿ Volume "docker-compose-drupal-practice_database"...
⠿ Volume "docker-compose-drupal-practice_drupal-modules"...
⠿ Volume "docker-compose-drupal-practice_drupal-profiles"...
⠿ Volume "docker-compose-drupal-practice_drupal-sites"...
⠿ Volume "docker-compose-drupal-practice_drupal-themes"...
⠿ Container database...
⠿ Container drupal...

接著打開瀏覽器輸入 http://localhost:8080,就會看到下方的畫面:

Drupal 設定語言介面

選擇完自己熟悉的語言後,會到下一步,這次練習的重點並不在 Drupal 身上,所以選擇標準就可以了。

安裝設定檔

接著就會是設定資料庫的頁面,記得最上面要選擇是 PostgreSQL 的類型。

這邊的資料庫名稱、使用者名稱、密碼等等,將根據您傳入的環境變數作為答案,也就是 docker-compose.yml 裡面關於 postgres 的設定。

您應該會放在 .env 檔案內,並且讓 Docker Compose 自動注入。

以及下面的進階選項點開會發現,原本預設的主機是 localhost,我們有提過,對於容器來說 localhost 就等於是容器本身,所以會造成找不到資料庫的錯誤。

這裡要填入的則是您在 docker-compose.yml 中 servcies 內給予 postgres 這個容器的名字,作為其在虛擬網路中的 DNS。

設定資料庫

填寫完畢且沒有任何問題的話,Drupal 就會進入自動安裝的環節。

安裝 Drupal 中

安裝完後,關於網站的設定就交給讀者們自己去設定了,之後會進入到後台的管理系統,先看看尚未設定前的前台畫面。

未設定的前台畫面

為了測試 drupal 的 volume 都有正確的執行,可以點擊 外觀 的按鈕,隨便選擇一個外觀進行安裝並且設定為預設,接著前台的畫面就會改變,如下圖:

更改外觀後的前台畫面

再來是點擊 內容 的按鈕,新增一個最新消息來測試資料庫是否有正確的儲存資料,新增完文章後,可以在前台看到文章:

新增的文章

接著回到終端機,輸入 docker compose down 的指令來刪除容器以及虛擬網路。

$ docker compose down
[+] Running 3/2
⠿ Container drupal Removed
⠿ Container database Removed
⠿ Network docker-compose-drupal-practice_default Removed

刪除後,再次輸入 docker compose up --detach 的指令啟動整個 drupal 應用程式,回到瀏覽器輸入 http://localhost:8080,若是 volumes 都有正確的設定,會看到畫面和之前一樣,儲存著應用程式的狀態。

客製化映像檔並且 Compose Up 練習

每一個章節都會提供一些小小的練習來熟悉本章的內容,通常會比較難一點;若是想不出來也不需要灰心,有些時候可能是指令不熟悉導致,可以往前翻閱來加強記憶喔,亦或是翻到後面的解答章節也可以幫助你解惑喔,記得 --help 以及 docs.docker.com 會是你最好的夥伴。

在上一個練習中,我們的映像檔是使用官方所提供的。 但其實 Drupal 有提供許多精美的主題可以套用,這時候我們可以透過自己客製化映像檔,在啟動 Docker Compose 之前就透過 Git 下載新的主題到 Drupal 中,以便讓我們可以在啟動後可以選擇好看的主題。

同時也可以練習到在 docker-compose.yml 內寫 build 的參數是什麼樣的效果。

  1. 撰寫 Dockerfile 以 drupal:latest 映像檔為基底
  2. 執行 apt-get update && apt-get install -y git 指令
  3. 接著執行 rm -rf /var/lib/apt/lists/*,記得使用\ 以及 && 來串連起一段指令,避免產生兩個映像層
  4. 接著 WORKDIR 到 /var/www/html/themes
  5. 再來執行 git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git
  6. 並且串連更改權限的指令 chown -R www-data:www-data bootstrap
  7. 最後 WORKDIR 到 /var/www/html
  8. 在 docker-compose.yml 內加入 build 的參數,並且以 docker compose up --build --detach 的方式啟動
  9. 啟動後,打開瀏覽器輸入 http://localhost:8080,點擊 外觀 的按鈕,可以看到我們客製化放進去的 bootstrap 主題

客製化映像檔並且 Compose Up 練習解答

答案可以在本書的 GitHub 儲存庫中 ch-06 內的docker-compose-custom-drupal-image-answer 中找到。

  1. 撰寫 Dockerfile 以 drupal:latest 映像檔為基底
FROM drupal:latest
  1. 執行 apt-get update && apt-get install -y git 指令

透過 apt 套件工具安裝 Git,以便於後面可以利用 Git 來安裝新的主題

FROM drupal:latest

RUN apt-get update && apt-get install -y git
  1. 接著執行 rm -rf /var/lib/apt/lists/*,記得使用\ 以及 && 來串連起一段指令,避免產生兩個映像層

此指令的動作是清理 apt-get install 後殘留下來的不需要的檔案,可以參考 drupal 官方映像檔的作法。

FROM drupal:latest

RUN apt-get update && apt-get install -y git && \
rm -f /var/lib/apt/lists/*
  1. 接著 WORKDIR 到 /var/www/html/themes

先進入到存放主題的資料夾內,以便下一個指令能夠安裝在正確的資料夾內。

FROM drupal:latest

RUN apt-get update && apt-get install -y git && \
rm -f /var/lib/apt/lists/*

WORKDIR /var/www/html/themes
  1. 再來執行 git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git

安裝 bootstrap 的主題

FROM drupal:latest

RUN apt-get update && apt-get install -y git && \
rm -f /var/lib/apt/lists/*

WORKDIR /var/www/html/themes

RUN git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git
  1. 並且串連更改權限的指令 chown -R www-data:www-data bootstrap

此指令的目的是改變我們下載的 bootstrap 資料夾的權限,而 www-data 則是 drupal 官方映像檔所預設的使用者,所以我們也把資料夾的權限改為預設的使用者 www-data。

FROM drupal:latest

RUN apt-get update && apt-get install -y git && \
rm -f /var/lib/apt/lists/*

WORKDIR /var/www/html/themes

RUN git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git && \
chown -R www-data:www-data bootstrap
  1. 最後 WORKDIR 到 /var/www/html

為何最後還要回到這個資料夾呢?原因在於官方的映像檔最後也是預設停留在這個資料夾內,為了不讓啟動時出現非預期的錯誤,這邊必須遵循官方映像檔的設定。

FROM drupal:latest

RUN apt-get update && apt-get install -y git && \
rm -f /var/lib/apt/lists/*

WORKDIR /var/www/html/themes

RUN git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git && \
chown -R www-data:www-data bootstrap

WORKDIR /var/www/html
  1. 在 docker-compose.yml 內加入 build 的參數,並且以 docker compose up --build --detach 的方式啟動

這邊的 docker-compose.yml 和上一個練習的內容幾乎大同小異,差別就在於 build 的參數設定,如下面所示:

version: '3.9'

services:
drupal:
image: custom-drupal
build: <- 建置映像檔
context: .
dockerfile: Dockerfile
container_name: drupal
ports:
- 8080:80
volumes:
- drupal-modules:/var/www/html/modules
- drupal-profiles:/var/www/html/profiles
- drupal-sites:/var/www/html/sites
- drupal-themes:/var/www/html/themes

database:
image: postgres:14-alpine
container_name: database
enviroment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- database:/var/lib/postgresql/data

volumes:
drupal-modules:
drupal-profiles:
drupal-sites:
drupal-themes:
database:

接著輸入 docker compose up --build --detach,就會根據當前目錄中的 Dockerfile 來建置客製化的 drupal 映像檔。

$ docker compose up --build --detach
[+] Building 0.6s (9/9) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 32B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/drupal:latest
=> [1/5] FROM docker.io/library/drupal:latest
=> CACHED [2/5] RUN apt-get update && apt-get install -y g...
=> CACHED [3/5] WORKDIR /var/www/html/themes
=> CACHED [4/5] RUN git clone --branch 8.x-3.x ...
=> CACHED [5/5] WORKDIR /var/www/html
=> exporting to image
=> => exporting layers
=> => writing image sha256:a5d6d0711a4d228d3ec1d041...
=> => naming to docker.io/library/custom-drupal
[+] Running 8/8
⠿ Network docker-compose-custom-drupal-image-answer_default
⠿ Volume "docker-compose-custom-drupal-image-answer_drup.."
⠿ Volume "docker-compose-custom-drupal-image-answer..."
⠿ Volume "docker-compose-custom-drupal-im...."
⠿ Volume "docker-compose-custom-drupal-image-answe..."
⠿ Volume "docker-compose-custom-drupal-image-answer_database"
⠿ Container drupal
⠿ Container database
  1. 啟動後,打開瀏覽器輸入 http://localhost:8080,點擊 外觀 的按鈕,可以看到我們客製化放進去的 bootstrap 主題

前面的設定方式都和上一個練習一樣,最重要的就是要確認客製化映像檔是否有效,只要看到外觀內有 Bootstrap 的主題,就證明了我們透過自己撰寫 Dockerfile 來加入新的主題,如下圖。

Bootstrap 的主題

看到 Bootstrap 主題後,就可以算是完成這個練習了!