首頁

目前文章總數:190 篇

  

最後更新:2025年 07月 26日

0017. LinuxServer.io 實戰:Deploy BookStack + MariaDB with Docker Compose

日期:2025年 07月 26日

標籤: Linux Ubuntu Docker Docker-Compose Container BookStack MariaDB LinuxServer.io Portaniner

摘要:資訊筆記


應用所需:1. Linux 主機(本篇 Linux Ubuntu 22.04 作業系統)
     2. 已安裝 Docker-Compose (Docker ≥ 20.x(rootful)、docker‑compose ≥ v2)
解決問題:1. LinuxServer.io 介紹、如何使用、為何要使用
     2. 用了 LinuxServer.io 的 Image 可以達到部署環境一致性、穩定的 Image
     3. 實作 LinuxServer.io 支援的 BookStack 結合 MariaDB 的部署實作
基本介紹:本篇分為 4 大部分。
第一部分:LinuxServer.io 初探
第二部分:LinuxServer.io 維護與 CI 流程說明
第三部分:實戰部署 BookStack + MariaDB
第四部分:DEMO 成果






第一部分:LinuxServer.io 初探

Step 1:介紹 LinuxServer.io

LinuxServer.io 官網首頁有以下資訊:

Building and maintaining community images
We are a group of like-minded enthusiasts from across the world who build and maintain the largest collection of Docker images on the web, and at our core are the principles behind Free and Open Source Software. Our primary goal is to provide easy-to-use and streamlined Docker images with clear and concise documentation.


簡要大意:理念是自由與開源,讓所有熱心者一起維護 LinuxServer.io,一起打造精簡好用的 Docker Image文件

Step 2:緒論:為何使用 LinuxServer.io

選用 LinuxServer.io 來部署網站有以下好處:

項目 具體內容
1. 社群維護與 CI 流程 每日自動建構、同時支援 x86‑64 & ARM64。
2. 一致的參數規格 環境變數、Volume 掛載點、健康檢查都遵循相同模板。
3. 可控性 提供 :latest 與版本化 tag(如 10.11.8-ls50),方便在部署環境使用穩定版本。


其中社群維護與 CI 流程 是讓容器使用者在「社群維護但非官方支援」的情境下,依然有高度可預期性

Step 3:LinuxServer.io - 優點、缺點

並且依照好處可以定義出以下優點:

1. 一致性高(標準化良好) 所有映像都採用統一的基礎配置
  - PUID / PGID 權限設計 → 避免容器內寫檔權限問題
  - TZ、UMASK、Volume 掛載、健康檢查等環境變數設計
  - 建構流程統一,方便熟悉後快速套用到不同服務
  - 適合系統管理員與 DevOps 團隊快速導入、部署。
2. 支援多平台架構(Multi-Arch) 跨平台友善
  - 標準伺服器或 VM
  - Raspberry Pi、ARM NAS(如 Synology、Unraid)
3. 自動化 CI 驗證 內建每日自動建構,包含安全更新
  - 自動檢查上游版本是否更新 → 最新版自動發布
  - 基底映像一有安全性修補(如 CVE)會自動重建
4. 開源-全免費 全部免費,沒有綁定付費
  - Dockerfile 與 Jenkinsfile 全部在 GitHub 上公開



對應的缺點如下:

1. 非官方映像 潛在兼容風險與無法正確使用
  - 並非由上游專案(如 BookStack、GitHub Desktop)官方維護
  - 上游改變架構、檔案路徑時可能會發生不相容
2. 相對依賴 LinuxServer 社群活躍度 目前仍持續活躍
  - 若維護者不再維護某映像,可能無法即時支援新版本
  - 某些冷門映像建構頻率低、PR 合併速度慢
  - 已安裝的映象檔,未來仍可能被捨棄,導致部署失效
3. 進階自訂需求可能受限 無法任意移除參數
  - 採用 s6-overlay 啟動流程,若你需完全自訂 Entrypoint 可能不夠靈活
  - 不適合需要極度高度客製化 base image 的情況(如內嵌 LDAP、特殊模組)
4. CI 系統透明但非開放共建 需要審核通過才可上傳 Image
  - 雖然建構過程透明,但不接受所有人推送映像到官方 registry
  - 必須由 LinuxServer 團隊 Merge 才會正式釋出


Step 4:收費標準 - 完全免費

官網捐獻有以下資訊:

Donations
Even the smallest donation from you will help us keep everything up and running so we can continue to provide our great services. We are always eternally grateful for the donations we receive. Everyone at LinuxServer is a volunteer. We don't get paid to do this — we try our best to make the most of our free time to continue improving what we do. If you love what we do, please consider helping us by either donating or contributing to our budget. Cheers!


簡要的說:完全免費,如果願意捐獻 LinuxServer.IO 的開源開發人員會很感謝您。

多架構 manifest

Step 5:Image 文件使用方法

LinuxServer.io 官方文件收錄所有貢獻者撰寫的文件
本篇會介紹 BookStack 與 MariaDB 的安裝方法

Step 6:一致性 - 什麼是 s6-overlay

LinuxServer.io 的好處是:所有映像(如 Jellyfin、MariaDB、BookStack)都用 s6-overlay 作為初始化機制。
其中 s6-overlay 是一個用在 Docker 容器中的 init system(初始化與監控系統),主要以下 3 點:

1. 控制服務啟動順序 確保容器中服務按正確順序啟動(例如先啟動資料夾掛載、再啟動主程式)
2. 處理容器內 signal(如關機) 正常處理訊號,避免資料庫「強制中斷」造成損毀
3. 支援健康檢查、日誌管理 統一所有 LinuxServer.io 容器的 log、status 行為


簡化:部署者不需要學每個 image 各自的 entrypoint 腳本,減少看說明文件的時間。

Step 7:一致性 - 什麼是 PUID / PGID

LinuxServer.io 為了解決「容器內檔案權限對宿主機不一致」的通用解法就是採用 PUID / PGID:

名稱 作用 說明
PUID Process User ID 控制容器中程式以哪個 UID 執行
PGID Process Group ID 控制所屬群組


上述 2 個參數可以在 docker-compose.yml 配置

environment:
  - PUID=1000
  - PGID=1000


因此總是採用此方法的 LinuxServer.IO 有以下優點:

1. 宿主機的資料夾(volume)和容器中的權限一致
2. 可以直接編輯掛載資料夾,不會遇到「寫入權限不足」的情況
3. 多人協作時,可以用不同 UID/群組控管存取權限


Step 8:一致性 - 什麼是「多架構 manifest」

Docker Hub(或 LinuxServer.io)上的一個映像,如果支援多架構(multi-arch),就會提供一個 manifest list
當我們要 Pull LinuxServer.io 上的 Image 時,會自動偵測您的硬體架構(x86-64 或 arm64)
例如在 Ubuntu 上 pull LinuxServer.IO 的 bookStack Image,就會依照適合您的硬體下載

docker pull lscr.io/linuxserver/bookstack


因此 x86-64(桌機/雲端)、arm64(樹莓派 / NAS / Apple M )都可以正常使用對應機器的 Image。



第二部分:LinuxServer.io 維護與 CI 流程說明

Step 1:為什麼 LinuxServer.io 每日自動建構

這背後其實是為了 穩定性、安全性、架構相容性 的考量,讓容器使用者在「社群維護但非官方支援」的情境下,依然有高度可預期性。

原因 目的
1. 安全更新跟得上 基底映像修補漏洞,自動整合
2. 穩定版本產出 時發現失敗或變更造成問題
3. 架構完整測試 確保 ARM64 和 x86 都能成功建構
4. 易除錯、好監控 透過 CI pipeline 能追溯問題源頭


LinuxServer.IO Jenkins 定時 Poller Jenkins 外部 Job ➜ 查 GitHub API ➜ 偵測新 release ➜ 觸發建置。
確保信賴的 Image 有更新 Release 簽入時,可以同步更新。

Step 2:檢視 Docs

官網首頁 -> Docs

Step 3:前往官方 CI 網站

官方 CI 網站

Step 4:檢視資料夾 - Docker-Pipeline-Builders

只有被列入持續維護的 Image 會被加入至 CI 中持續監控。

Step 5:以 github-desktop 為例

上次更新成功時間為 1小時 18 分,表示有觸發 Jenkins Trigger,但是否有更新仍要進入查看

Step 6:github-desktop - 最近更新時間

進入後,可以觀察到上次更新時間為 2025/6/28 日,此篇記錄於 2025/7/2,因此點擊 Pipeline 中的異動紀錄 githubweb

Step 7:github-desktop - 觸發更新的原因

可以觀察到,因為 3 天前(2025/6/28) github-desktop 有簽入 release-3.4.13-linux1-ls147 版本
LinuxServer.io 觸發到 Jenkins 建置條件,並且建置是成功的,表示此版本的 Image 在 LinuxServer.io 上是可信賴的
※仍非官方正式公佈的 Image,但說明了為何 LinuxServer.io 需要保持自動 Trigger 檢查建置,達到 Image 可用。



第三部分:實戰部署 BookStack +  MariaDB

Step 1:BookStack - 進入 Image 頁籤

進入 LinuxServer.io 後依序如圖點擊

1. Image
2. Search 輸入框輸入 bookstack
3. 進入此文件頁面



Step 2:BookStack - 文件 - 介紹

進入後,會有 LinuxServer.io 對 BookStack 的介紹

Bookstack is a free and open source Wiki designed for creating beautiful documentation. Featuring a simple, but powerful WYSIWYG editor it allows for teams to create detailed and useful documentation with ease.

Powered by SQL and including a Markdown editor for those who prefer it, BookStack is geared towards making documentation more of a pleasure than a chore.

For more information on BookStack visit their website and check it out:


簡要的說:BookStack 是一個免費且開源的 Wiki 系統,介面美觀、易於使用,適合用於團隊的知識管理。
※特別適合產品或開發團隊撰寫與維護文件。從應用層面來看,可視為 Confluence 的免費替代方案,但在功能完整性與擴展性上略遜於 Confluence。

Step 3:BookStack - 文件 - 應用架構

會提供此 Image 的應用架構,如圖所示,支援了 x86-64 / arm64

Step 4:BookStack - 文件 - 應用設定

此段落提示了 BookStack 強制綁定 MariaDB ; 預設密碼為 password ; 預設帳號 admin@admin.com
並且請注意一定要設定 APP_URL 進行外部域名訪問 ; 使用的容器 Port: 6875

Step 5:BookStack - 文件 - 檔案生成路徑

容器運行後,會自動生成 BookStack 相對路徑下的 /config 資料夾,存放相關文件

Step 6:準備 docker-compose.yml - BookStack

最關鍵的部分是關於 docker-compose.yml 的文件,裡面有定義使用的方法,給出預設的模板
直接使用 100% 無法運行,還需要對空白的地方做設置,其中還需要補充上 MariaDB 的部分

---
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - APP_URL=
      - APP_KEY=
      - DB_HOST=
      - DB_PORT=3306
      - DB_USERNAME=
      - DB_PASSWORD=
      - DB_DATABASE=
      - QUEUE_CONNECTION= #optional
    volumes:
      - /path/to/bookstack/config:/config
    ports:
      - 6875:80
    restart: unless-stopped



Step 6:準備 docker-compose.yml - MariaDB

LinuxServer.io 的 MariaDB 查找方式同第三部分 Step1 - Step4,就不重覆
我們將 MariaDB docker-compose的部分進行複製,並且也需要對空白的部分作設置

---
services:
  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: mariadb
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD
      - MYSQL_DATABASE=USER_DB_NAME #optional
      - MYSQL_USER=MYSQL_USER #optional
      - MYSQL_PASSWORD=DATABASE_PASSWORD #optional
      - REMOTE_SQL=http://URL1/your.sql,https://URL2/your.sql #optional
    volumes:
      - /path/to/mariadb/config:/config
    ports:
      - 3306:3306
    restart: unless-stopped



Step 7:完成 docker-compose.yml - MariaDB + BookStack

組成後會有以下的設定,關於 BookStack 異動的部分:

APP_LANG 為了中文化,額外設定 zh_TW
TZ BookStack 容器的時區位置,由Etc/UTC 改為 Asia/Taipei
APP_URL 依照自己主機的位置配置,我的主機是 192.168.51.28 加上文件寫 port 使用 6875
APP_KEY 保留,目前還不能配置
DB_HOST 對應資料庫 MariaDB 容器的名稱 mariadb (資料庫必須使用 MariaDB)
DB_PORT MariaDB 開啟的 Port 號
DB_USERNAME 對應 MariaDB 訪問帳號
DB_PASSWORD 對應 MariaDB 訪問密碼
DB_DATABASE 對應 MariaDB 可訪問資料庫
volumes BookStack 建立時 Config 的產生位置,調整為此 docker-compose.yml 文件下的生成對應目錄 config
depends_on 依賴的容器 mariadb


組成後會有以下的設定,關於 MariaDB 異動的部分:

TZ MariaDB 容器的時區位置,由Etc/UTC 改為 Asia/Taipei
MYSQL_ROOT_PASSWORD 建立時 Root 的密碼
MYSQL_DATABASE 建立時定義的資料庫名稱
MYSQL_USER 可訪問此資料庫的帳號
MYSQL_PASSWORD 可訪問此資料庫的密碼
REMOTE_SQL 移除,我們不用對外訪問此資料庫,只提供給 BookStack 使用
volumes MariaDB 建立時 Config 的產生位置,調整為此 docker-compose.yml 文件下的生成對應目錄 config
---
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - APP_LANG=zh_TW
      - TZ=Asia/Taipei
      - APP_URL=http://192.168.51.28:6875
      - APP_KEY=
      - DB_HOST=mariadb
      - DB_PORT=3306
      - DB_USERNAME=bookstack          
      - DB_PASSWORD=bookstack123       
      - DB_DATABASE=bookstackapp       
    volumes:
      - ./bookstack-config:/config     
    ports:
      - 6875:80
    restart: unless-stopped
    depends_on:
      - mariadb

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: mariadb
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Taipei
      - MYSQL_ROOT_PASSWORD=rootpassword123    
      - MYSQL_DATABASE=bookstackapp            
      - MYSQL_USER=bookstack                   
      - MYSQL_PASSWORD=bookstack123            
    volumes:
      - ./mariadb-config:/config               
    ports:
      - 3306:3306
    restart: unless-stopped


Step 8:配置 docker-compose.yml 到 Ubuntu 主機上

將 Step 7. 中組成的 docker-compose.yml 部署到遠端機器上
我的內部機器是 192.168.51.28,存放位置 louistemp//bookstack

Step 9:執行指令

進入 Ubuntu 主機後,到 docker-compose.yml 對應的目錄下,執行:

docker-compose up -d


安裝完成!

Step 10:嘗試訪問 - 失敗

這時嘗試登入會出現錯誤是正常的,因為我們尚未設定金鑰

http://192.168.51.28:6875



Step 11:訪問容器 - 確認指令

可以透過 Portainer 或者下指令的方式查看容器的 Log
目前缺少金鑰,要求我們生成

Step 12:產生 BookStack APP_KEY

接著可以輸入以下容器給出的指令,我們可以獲得此機器上的金鑰

docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey



Step 13:更新 docker-compose 檔案的 APP_KEY

將 APP_KEY 貼上至 docker-compose.yml 的對應位置

Step 14:重新執行 docker-compose

接著重建 docker-compose ,依序輸入以下:

docker-compose down -v
docker-compose up -d



Step 15:再次訪問 - 成功

最後,再次訪問,BookStack + MariaDB 容器就建立完成



第四部分:Demo 成果

Step 1:Demo 成果 - 登入成功

我們使用 LinuxServer.io 中 BookStack 的文件給出的預設帳號、密碼,進行登入
預設帳號 admin@admin.com
預設密碼 password
成功登入 - 可以使用 BookStack 享受知識管理的樂趣了