使用 Docker 和 Traefik v2 搭建 Confluence 7.3

  • 2020 年 3 月 13 日
  • 筆記

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或重新修改使用,但需要註明來源。 署名 4.0 國際 (CC BY 4.0)

本文作者: 蘇洋

創建時間: 2020年03月06日 統計字數: 7821字 閱讀時間: 16分鐘閱讀 本文鏈接: https://soulteary.com/2020/03/06/confluence-7-with-docker.html


使用 Docker 和 Traefik v2 搭建 Confluence 7.3

之前寫過三篇如何使用「容器化方案來搭建 Confluence」,本文將基於最近最新推出的 Confluence 7.3 來演示如何使用新版的軟體。

如果你想要給公司團隊或者個人搭建 Wiki,可以參考之前關於如何搭建 Wiki 的實戰文章,裡面記錄了如何高效完成搭建,並避過踩坑的方法。

以往已經上車使用的用戶,也可以參考本文進行升級。

寫在前面

在獨立運行維護多個 Confluence 實例一年多之後,經歷了多次的升級維護,確認了使用容器比宿主機直接安裝是更為有效的維護方式。

因為首先,你的操作能夠都被版本化的記錄下來,如同管理程式碼一般;其次,需要去維護和管理的內容,只是極少一部分變數,而非整個環境。

官方對於容器是積極但是還不夠嚴謹,從過往一年來看:

  • 在 2019 年裡,confluence 官方因為一個嚴重漏洞,重新發布並覆蓋了以往所有的容器鏡像,導致文件許可權和卷掛載出現過問題。
  • 在 2019 年裡,官方鏡像缺少必要參數,導致用戶不得不修改文件,並掛載到容器內部。
  • 在 2020 年初,官方升級插件市場的證書,而未更新容器根證書,導致容器啟動服務插件下載失敗。
  • 在 2020 年初,官方放棄了 alpine 鏡像發布。
  • ...

雖然問題多多,但是總體而言,還是很值得期待的畢竟高頻率的周更/月更,加活躍的社區和市場,支援「mb4字符集」,構建出了一個可以碾壓任何同類的商業化 Wiki 產品。

對於個人而言,只需要每年付費 10$ ,就能滿足一個10人初期團隊的使用,並且在 2020 年,使用 2G 記憶體的伺服器也能愉快的運行 Confluence 了。

當然,我更推薦 4G及以上的配置。

基礎準備

  • Docker Hub 上官方容器鏡像: https://hub.docker.com/r/atlassian/confluence-server/tags
    • 本文將基於 7 系列新版本: 7.3
  • MySQL JDBC Connector : https://dev.mysql.com/downloads/connector/j/5.1.html
    • 如果你也選擇使用 MySQL 作為儲存後端,需要下載此文件,一般情況下你會獲得 mysql-connector-java-5.1.47.tar.gz 的壓縮包,解壓縮之後,獲得 mysql-connector-java-5.1.47.jar,我們稍後會用到。
  • 一些中文字體,比如 simsun.ttc、 simkai.ttf等,如果你需要使用「導出文檔為 PDF、Word」功能,並且文檔包含中文,為了渲染正常,你需要提供一些中文字體。

基礎容器化

參考去年寫的文章《使用 Docker 搭建 Confluence》、以及今年「Traefik 2.x 版本升級」的文章指引,不難寫出下面的基礎配置。

version: '3'    services:      confluence:      image: atlassian/confluence-server:7.3.2-ubuntu      container_name: confluence-app      expose:        - 8090        - 8091      networks:        - traefik      labels:        - "traefik.enable=true"        - "traefik.docker.network=traefik"        - "traefik.http.routers.wiki-web.middlewares=https-redirect@file"        - "traefik.http.routers.wiki-web.entrypoints=http"        - "traefik.http.routers.wiki-web.rule=Host(`wiki.lab.com`)"        - "traefik.http.routers.wiki-ssl.middlewares=content-compress@file"        - "traefik.http.routers.wiki-ssl.entrypoints=https"        - "traefik.http.routers.wiki-ssl.tls=true"        - "traefik.http.routers.wiki-ssl.rule=Host(`wiki.lab.com`)"        - "traefik.http.services.wiki-backend.loadbalancer.server.scheme=http"        - "traefik.http.services.wiki-backend.loadbalancer.server.port=8090"      environment:        - 'CATALINA_OPTS=-Duser.timezone=GMT+08 -Dconfluence.document.conversion.fontpath=/usr/local/share/fonts/'        - 'JVM_MINIMUM_MEMORY=1024m'        - 'JVM_MAXIMUM_MEMORY=2048m'      volumes:        - ./data:/var/atlassian/application-data/confluence        - ./deps/confluence/mysql-connector-java-5.1.47.jar:/opt/atlassian/confluence/confluence/WEB-INF/lib/mysql-connector-java-5.1.47.jar        - ./fonts:/usr/local/share/fonts        - /etc/localtime:/etc/localtime:ro      extra_hosts:        - 'wiki.lab.com:127.0.0.1'    networks:    traefik:      external: true

上面的配置幾乎完美,將上面的內容保存為 docker-compose.yml 後,使用 docker-compose up-d 啟動應用,你就能夠得到一個新版本的 Confluence 了。

需要解決的問題

但是這樣運行起來的 Confluence 會遇到一些問題:

  • 後台登陸提示你需要修正代理配置
  • 插件市場因為官方變更服務域名,鏡像證書比較陳舊導致無法使用

接下來,我們就來解決這些問題。

後台提示需要修正域名配置

這個問題常常出現在使用了反向代理、負載均衡給 Confluence 掛載證書的情況下,在以往的版本中,我們需要添加 server.xml 並進行文件只讀鎖定,來解決這個問題。

官方文檔稍顯陳舊,但是也記錄過這個問題:《Can't check base URL warning in Confluence 6.6 or later》。

但是在新版本中,我們可以通過設置容器運行環境變數來解決這個問題,不過這裡有一個 Tricks 的事情,如果你不創建並掛載 server.xml 這個文件,你將無法解決這個問題。

首先創建 server.xml 文件:

<?xml version="1.0" encoding="utf-8"?>    <Server port="8000"          shutdown="SHUTDOWN">      <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>    <Listener className="org.apache.catalina.core.AprLifecycleListener"              SSLEngine="on"/>    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>      <Service name="Catalina">        <Connector port="8090"                 maxThreads="100"                 minSpareThreads="10"                 connectionTimeout="20000"                 enableLookups="false"                 protocol="HTTP/1.1"                 redirectPort="8443"                 acceptCount="10"                 secure="false"                 scheme="https"                 proxyName="wiki.lab.com"                 proxyPort="443"                   relaxedPathChars="[]|"                 relaxedQueryChars="[]|{}^`&quot;&lt;&gt;"                 bindOnInit="false"                 maxHttpHeaderSize="8192"                 useBodyEncodingForURI="true"                 disableUploadTimeout="true" />        <Engine name="Standalone"              defaultHost="localhost"              debug="0">        <Host name="localhost"              debug="0"              appBase="webapps"              unpackWARs="true"              autoDeploy="false"              startStopThreads="4">          <Context path=""                   docBase="../confluence"                   debug="0"                   reloadable="false"                   useHttpOnly="true">            <!-- Logging configuration for Confluence is specified in confluence/WEB-INF/classes/log4j.properties -->            <Manager pathname=""/>            <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve"                   threshold="60"/>          </Context>            <Context path="${confluence.context.path}/synchrony-proxy"                   docBase="../synchrony-proxy"                   debug="0"                   reloadable="false"                   useHttpOnly="true">            <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve"                   threshold="60"/>          </Context>          </Host>      </Engine>      </Service>    </Server>

接著在容器編排文件中添加掛載命令:

volumes:    - ./deps/confluence/server.xml:/opt/atlassian/confluence/conf/server.xml

最後,在編排文件中添加環境變數:

environment:    - 'CATALINA_CONNECTOR_PROXYNAME=wiki.lab.com'    - 'CATALINA_CONNECTOR_PROXYPORT=443'    - 'CATALINA_CONNECTOR_SCHEME=https'

最後,重啟你的應用就好了。

插件市場提示不能訪問

這個問題其實挺麻煩的,我實際運行的時候,主進程沒有報任何錯誤,但是根據以往封裝鏡像的經驗,判斷是 JRE 證書信任問題,找到了官方相關的一些資料

  • 《The Atlassian Marketplace Server is not Reachable Due to Peer Not Authenticated》
  • 《SSL Handshake Error When Connecting to Atlassian Marketplace》

這個問題其實應該說是一個老問題了,從2012 年、2014 年以及之後頻出。而上面這些標記為 7.3 版本使用的資料其實只是一個線索,不能直接使用。

想要知道原因嗎?且往下看。

如何添加並信任新的證書

想信任新的證書,先得先獲取新的證書文件,使用 openssl 工具將證書保存為文件。

openssl s_client -connect marketplace.atlassian.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > marketplace.atlassian.com.crt

以往的文章,針對的是老版本的 JDK(低於10),使用 keytool 導入證書就行了。

keytool -import -trustcacerts -alias proxy_root -file marketplace.atlassian.com.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt

上面的操作,可以解決 confluence 5.x / 6.x 的問題,而在 confluence 7.x 中,JDK 升級為了 11,儲存位置有了變化。Oracle 官方部落格有記錄《OpenJDK 10 Now Includes Root CA Certificates》這個變更。所以命令需要變更為:

keytool -import -trustcacerts -alias proxy_root -file marketplace.atlassian.com.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt

讓「修補程式操作」持久化

如果是宿主機安裝的話,執行上面的操作,然後重啟進程就好了。

但是我們使用的是運行過程「無狀態」的容器,對於官方容器作出任何改變,並重啟,這些「變更」會自然而然的隨著容器沙盒銷毀而銷毀。(如果沒有使用特殊的 daemon 進程方案的話)

所以這裡需要基於官方鏡像,訂製一個修補程式鏡像,內容很簡單。

FROM atlassian/confluence-server:7.3.2-ubuntu  LABEL maintainer="[email protected]"    USER root    RUN openssl s_client -connect marketplace.atlassian.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/marketplace.atlassian.com.crt  RUN keytool -import -trustcacerts -alias proxy_root -file /tmp/marketplace.atlassian.com.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt    USER confluence

使用 docker build-t confluence-server:7.3.2-ubuntu-fix. 將新的容器鏡像命名為 * confluence-server:7.3.2-ubuntu-fix*。

然後在編排文件中,替換鏡像名稱,再次啟動容器,插件市場就能正常訪問了。

image: confluence-server:7.3.2-ubuntu-fix

修正後的編排配置

為了方便使用,這樣提供一個完整的配置文件。

version: '3'    services:      confluence:      image: confluence-server:7.3.2-ubuntu-fix      container_name: confluence-app      expose:        - 8090        - 8091      networks:        - traefik      labels:        - "traefik.enable=true"        - "traefik.docker.network=traefik"        - "traefik.http.routers.wiki-web.middlewares=https-redirect@file"        - "traefik.http.routers.wiki-web.entrypoints=http"        - "traefik.http.routers.wiki-web.rule=Host(`wiki.lab.com`)"        - "traefik.http.routers.wiki-ssl.middlewares=content-compress@file"        - "traefik.http.routers.wiki-ssl.entrypoints=https"        - "traefik.http.routers.wiki-ssl.tls=true"        - "traefik.http.routers.wiki-ssl.rule=Host(`wiki.lab.com`)"        - "traefik.http.services.wiki-backend.loadbalancer.server.scheme=http"        - "traefik.http.services.wiki-backend.loadbalancer.server.port=8090"      environment:        - 'CATALINA_OPTS=-Duser.timezone=GMT+08 -Dconfluence.document.conversion.fontpath=/usr/local/share/fonts/'        - 'JVM_MINIMUM_MEMORY=1024m'        - 'JVM_MAXIMUM_MEMORY=2048m'        - 'CATALINA_CONNECTOR_PROXYNAME=wiki.lab.com'        - 'CATALINA_CONNECTOR_PROXYPORT=443'        - 'CATALINA_CONNECTOR_SCHEME=https'      volumes:        - ./data:/var/atlassian/application-data/confluence        - ./deps/confluence/mysql-connector-java-5.1.47.jar:/opt/atlassian/confluence/confluence/WEB-INF/lib/mysql-connector-java-5.1.47.jar        - ./fonts:/usr/local/share/fonts        - ./deps/confluence/server.xml:/opt/atlassian/confluence/conf/server.xml        - /etc/localtime:/etc/localtime:ro      extra_hosts:        - 'wiki.lab.com:127.0.0.1'    networks:    traefik:      external: true

其他

我個人建議作為生產環境使用,務必使用雲服務商的雲數據,安全性和可靠性更好,但是如果個人使用,本地啟動一個資料庫容器實例,也不是不可,參考官方建議文檔,可以將資料庫啟動參數調整為:

command: --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --default-storage-engine=INNODB --max_allowed_packet=256M --innodb_log_file_size=2GB --transaction-isolation=READ-COMMITTED --binlog_format=row

另外,如果你遇到了中文文件不能正常渲染的問題,可以參考下面這篇文章進行快取清理:

  • 《容器化 Confluence 使用拾遺》

最後

每次升級調整 Confluence 的過程,都是一種花式踩坑的過程,過程雖然很麻煩,但是踩過之後,依舊會忍不住的感嘆,個人使用每年 10$ 花的真值。

Tags: