從定製 Ghost 鏡像聊聊優化Dockerfile

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

本文做者: 蘇洋前端

建立時間: 2020年03月09日 統計字數: 6225字 閱讀時間: 13分鐘閱讀 本文連接: soulteary.com/2020/03/09/…node


從定製 Ghost 鏡像聊聊優化Dockerfile

《修理 Ghost 中文輸入法的 BUG》一文中,經過給源碼打補丁,並進行編譯的方式,咱們解決了 Ghost 的「陳年固疾」:不能正常輸入中文。git

兩個月過去了,Ghost 開啓了雞血模式,不講道理的更新了若干版本,從當時的 3.3.0 飆升至 3.9.0,考慮到項目中有依賴 Ghost,須要持續的更新維護,那麼就在這裏分享一下,如何更好的折騰它。github

寫在前面

GitHub 的倉庫中,咱們能夠看到,解決這個 Bug 須要兩步走:docker

  • 對管理後臺的前端實現代碼進行補丁,並從新構建
  • 對管理後臺的服務器端渲染模版進行更新

而在使用和維護上,必須考慮如下幾點:npm

  • 補丁內容是否會影響現有邏輯
  • 是否能夠不干擾用戶使用官方鏡像
  • 是否能夠儘量少/不編碼,實現鏡像的維護更新
  • 用於構建修正過前端功能的工具鏡像性能可否更高

因爲 Ghost 服務端腳本/模版不須要構建使用,咱們以修改處理比較「麻煩」的 Ghost 前端資源爲例,講講如何優化 Dockerfile。編程

優化構建鏡像

在代碼倉庫中,咱們能夠看到 Dockerfile 的內容是這樣編寫的:json

FROM node:12-alpine
LABEL maintainer="soulteary@gmail.com"
 
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

RUN echo '' > /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main"         >> /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community"    >> /etc/apk/repositories && \
    echo "Asia/Shanghai" > /etc/timezone

RUN apk update && apk add git && \
    yarn global add knex-migrator grunt-cli ember-cli bower

COPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.js

RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
    cd /mobiledoc-kit && \
    git checkout 3b0f375d32f7183a4eee9cce5373ebabeb249165 && \
    cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
    yarn && \
    cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
    rm -rf /mobiledoc-kit

RUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git /Ghost && \
    cd /Ghost && \
    git checkout 3.3.0 && \
    yarn setup

RUN rm -rf /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/dist && \
    cp -r /patches/mobiledoc-kit/dist /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/

WORKDIR /Ghost

RUN grunt prod

EXPOSE 2368

CMD ["npm", "start"]
複製代碼

這裏存在幾個問題:bash

  1. 「代碼版本」被硬編碼到了 Dockerfile 中,不利於mobiledoc-kitGhost 代碼升級管理。
  2. 對 Ghost 進行完整數據獲取,是沒有必要的。
  3. 咱們不肯定是否可以繼續對目標文件打補丁。

明確須要解決的問題以後,解決問題就容易多了。

解決硬編碼的問題

咱們首先須要將「版本」定義爲變量,而後抽象出來,考慮到不但願將來每次代碼升級都須要修改 Dockerfile,咱們可使用 它的 ARG 指令,對於原始內容進行優化,例如:

# FOR GHOST 3.9.0
ARG MOBILEDOC_KIT_VERSION=v0.11.1-ghost.4
RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
    cd /mobiledoc-kit && \
    git checkout $MOBILEDOC_KIT_VERSION && \
    cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
    yarn && \
    cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
    rm -rf /mobiledoc-kit
複製代碼

將來若是 Ghost 發佈 4.0.0,這個依賴的組件也有了版本變化,那麼在構建的時候只須要添加構建參數,便可完成新版本鏡像的構建,而不用在修改 Dockerfile,像是這樣:

docker build --build-arg MOBILEDOC_KIT_VERSION=v0.11.1-ghost.5
複製代碼

只獲取必要的代碼

原始的 Dockerfile 中,咱們獲取 Ghost 源碼將其整個倉庫都下載下來,在網絡條件很差的時候,很是影響構建。

因此能夠經過限定 depth 克隆深度,以及 branch 下載分支,限定要獲取的代碼量,只下有用的內容。

ARG GHOST_RELEASE_VERSION=3.9.0
RUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git --depth=1 --branch=$GHOST_RELEASE_VERSION /Ghost && \
    cd /Ghost && \
    yarn setup
複製代碼

判斷是否可以對當前文件打補丁

能夠判斷的方法不少,可是最簡單的自動化方案莫過於判斷代碼文件是否被修改過。

先使用 shasum 或者任何你用的順手的計算工具,對目標要進行補丁的文件進行校驗值計算,若是你使用的鏡像的基礎系統是 Ubuntu 可使用下面的方式進行校驗:

# 計算校驗值
shasum -a 256 path_to_project/event-manager.js

0faeb4eb1cd177f3d7972fda6c52a0089a4814171cedd5c43a7302f027b26723  path_to_project/event-manager.js

# 進行校驗
echo "0faeb4eb1cd177f3d7972fda6c52a0089a4814171cedd5c43a7302f027b26723 path_to_project/event-manager.js" | shasum -a 256 -c
複製代碼

這裏使用 Alpine 發行版做爲系統的容器,在不安裝額外軟件的狀況下,能夠換爲 md5sum 來進行計算,原來的 Dockerfile 能夠更新成下面這樣:

# FOR GHOST 3.9.0
ARG MOBILEDOC_KIT_VERSION=v0.11.1-ghost.4
ARG EVENT_MANAGER_HASH=9a0456060f1c816a0a66bdcf3363e928
RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
    cd /mobiledoc-kit && \
    git checkout $MOBILEDOC_KIT_VERSION && \
    (echo "$EVENT_MANAGER_HASH /mobiledoc-kit/src/js/editor/event-manager.js" | md5sum -c -s -) && \
    cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
    yarn && \
    cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
    rm -rf /mobiledoc-kit
複製代碼

若是校驗值和咱們傳遞的不一致,構建會自動中斷,若是發生這個情況,那麼理論來講咱們須要調整補丁邏輯,並計算出新的文件的校驗值。

完整的鏡像文件

爲了方便有相同需求的同窗,這裏給出完整的鏡像文件,相關代碼也已經上傳 GitHub

FROM node:12-alpine
LABEL maintainer="soulteary@gmail.com"

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

RUN echo '' > /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main"         >> /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community"    >> /etc/apk/repositories && \
    echo "Asia/Shanghai" > /etc/timezone

RUN apk update && apk add git && \
    yarn global add knex-migrator grunt-cli ember-cli bower

COPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.js

ARG GHOST_RELEASE_VERSION=3.9.0
RUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git --depth=1 --branch=$GHOST_RELEASE_VERSION /Ghost && \
    cd /Ghost && \
    yarn setup

# FOR GHOST 3.9.0
ARG MOBILEDOC_KIT_VERSION=v0.11.1-ghost.4
ARG EVENT_MANAGER_HASH=9a0456060f1c816a0a66bdcf3363e928
RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
    cd /mobiledoc-kit && \
    git checkout $MOBILEDOC_KIT_VERSION && \
    (echo "$EVENT_MANAGER_HASH /mobiledoc-kit/src/js/editor/event-manager.js" | md5sum -c -s -) && \
    cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
    yarn && \
    cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
    rm -rf /mobiledoc-kit

RUN rm -rf /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/dist && \
    cp -r /patches/mobiledoc-kit/dist /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/

WORKDIR /Ghost

RUN grunt prod

EXPOSE 2368

CMD ["npm", "start"]
複製代碼

其餘

處理軟件的版本更新,多多少少須要作一些簡單的分析,下面這些在線連接或許能夠幫到你(以此次處理 3.9.0 爲例):

  • 確認新舊版本差別:github.com/TryGhost/Gh…
    • 老版本須要放在前面,否則按照時間線,是必定對比不出內容的。
  • 確認新版本引用子模塊版本:github.com/TryGhost/Gh…
    • Ghost 的管理後臺、主題使用子模塊方式引入,須要單獨檢查並確認引用。
    • 也能夠 Clone 到本地,檢查 .submodule 文件,不過須要兩個步驟操做,略顯麻煩。
  • 確認新版本的子模塊依賴內容:github.com/TryGhost/Gh…
    • 檢查是否還存在 @tryghost/mobiledoc-kit 依賴,並確認其版本。
  • 確認編輯器組件模版:github.com/TryGhost/mo…
    • 確認模塊是有效的,而且查看是否有比較大的邏輯變動。

最後

下一篇 Ghost 相關的內容,或許會聊聊怎麼在容器中使用雲服務(oss/cos)對象儲存,以及如何搭配 SSO 單點登陸使用 Ghost。

--EOF


我如今有一個小小的折騰羣,裏面彙集了一些喜歡折騰的小夥伴。

在不發廣告的狀況下,咱們在裏面會一塊兒聊聊軟件、HomeLab、編程上的一些問題,也會在羣裏不按期的分享一些技術沙龍的資料。

喜歡折騰的小夥伴歡迎掃碼添加好友。(請註明來源和目的,不然不會經過審覈)

關於折騰羣入羣的那些事

相關文章
相關標籤/搜索