本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2020年03月09日
统计字数: 6225字
阅读时间: 13分钟阅读
本文链接: https://soulteary.com/2020/03/09/optimize-dockerfile-from-custom-ghost-image.html


从定制 Ghost 镜像聊聊优化 Dockerfile

在《修理 Ghost 中文输入法的 BUG》一文中,通过给源码打补丁,并进行编译的方式,我们解决了 Ghost 的“陈年固疾”:不能正常输入中文。

两个月过去了,Ghost 开启了鸡血模式,不讲道理的更新了若干版本,从当时的 3.3.0 飙升至 3.9.0,考虑到项目中有依赖 Ghost,需要持续的更新维护,那么就在这里分享一下,如何更好的折腾它。

写在前面

在GitHub 的仓库中,我们可以看到,解决这个 Bug 需要两步走:

  • 对管理后台的前端实现代码进行补丁,并重新构建
  • 对管理后台的服务器端渲染模版进行更新

而在使用和维护上,必须考虑以下几点:

  • 补丁内容是否会影响现有逻辑
  • 是否可以不干扰用户使用官方镜像
  • 是否可以尽可能少/不编码,实现镜像的维护更新
  • 用于构建修正过前端功能的工具镜像性能能否更高

由于 Ghost 服务端脚本/模版不需要构建使用,我们以修改处理比较“麻烦”的 Ghost 前端资源为例,讲讲如何优化 Dockerfile。

优化构建镜像

在代码仓库中,我们可以看到 Dockerfile 的内容是这样编写的:

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-8RUN 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/timezoneRUN apk update && apk add git && \yarn global add knex-migrator grunt-cli ember-cli bowerCOPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.jsRUN 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-kitRUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git /Ghost && \cd /Ghost && \git checkout 3.3.0 && \yarn setupRUN 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 /GhostRUN grunt prodEXPOSE 2368CMD ["npm", "start"]

这里存在几个问题:

  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.js0faeb4eb1cd177f3d7972fda6c52a0089a4814171cedd5c43a7302f027b26723  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-8RUN 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/timezoneRUN apk update && apk add git && \yarn global add knex-migrator grunt-cli ember-cli bowerCOPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.jsARG 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-kitRUN 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 /GhostRUN grunt prodEXPOSE 2368CMD ["npm", "start"]

其他

处理软件的版本更新,多多少少需要做一些简单的分析,下面这些在线链接或许可以帮到你(以这次处理 3.9.0 为例):

  • 确认新旧版本差异:https://github.com/TryGhost/Ghost/compare/3.3.0…3.9.0

    • 老版本需要放在前面,不然按照时间线,是一定对比不出内容的。
  • 确认新版本引用子模块版本:https://github.com/TryGhost/Ghost/tree/3.9.0/core
    • Ghost 的管理后台、主题使用子模块方式引入,需要单独检查并确认引用。
    • 也可以 Clone 到本地,检查 .submodule 文件,不过需要两个步骤操作,略显麻烦。
  • 确认新版本的子模块依赖内容:https://github.com/TryGhost/Ghost-Admin/blob/3.9.0/package.json
    • 检查是否还存在 @tryghost/mobiledoc-kit 依赖,并确认其版本。
  • 确认编辑器组件模版:https://github.com/TryGhost/mobiledoc-kit/compare/v0.11.1-ghost.4…3b0f375d32f7183a4eee9cce5373ebabeb249165
    • 确认模块是有效的,并且查看是否有比较大的逻辑变更。

最后

下一篇 Ghost 相关的内容,或许会聊聊怎么在容器中使用阿里云(oss)/腾讯云(cos)对象储存,以及如何搭配 SSO 单点登录使用 Ghost。

–EOF


我现在有一个小小的折腾群,里面聚集了一些喜欢折腾的小伙伴。

在不发广告的情况下,我们在里面会一起聊聊软件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的资料。

喜欢折腾的小伙伴欢迎扫码添加好友。(请注明来源和目的,否则不会通过审核)

关于折腾群入群的那些事

从定制 Ghost 镜像聊聊优化 Dockerfile相关推荐

  1. WINXP终极瘦身、优化、封装全攻略 万能WinXP Ghost镜像制作指南

    WINXP终极瘦身.优化.封装全攻略 万能WinXP Ghost镜像制作指南 重装系统可不是一件好玩的事情:首先得端坐在电脑桌前老老实实地回答windows安装程序提出的问题,安装好了呢,也不能闲着, ...

  2. 远景会员定制GHOST WIN7 2010珍藏版

    远景会员定制GHOST WIN7 2010珍藏版 ========================== * 使用WIN7 旗舰版制作,无人值守自动安装,无需输入序列号. * 安装完成后使用admini ...

  3. 我的docker随笔36:定制jenkins镜像

    本文涉及一种根据实际需求定制 jenkins 镜像的方法及实践.其目的是在官方镜像基础上添加自定义软件.库,以便更加适应项目的开发情况. 一.引言 官方镜像基本能实现了常见的持续集成功能,但还有一些不 ...

  4. Docker镜像的优化

    我们在使用docker镜像的时候会发现一些镜像运行的话会非常的大,占用系统资源,那么我们其实是可以通过优化来解决这样的问题的 镜像的优化准则: 选择最精简的基础镜像 减少镜像的层数 清理镜像构建的中间 ...

  5. 前端 Docker 镜像体积优化

    如果 2019 年技术圈有十大流行词,容器化肯定占有一席之地,随着 Docker 的风靡,前端领域应用到 Docker 的场景也越来越多,本文主要来讲述下开源的分布式图数据库 Nebula Graph ...

  6. Docker学习之路04:创建定制Nginx镜像

    Docker学习之路04:创建定制Nginx镜像 Docker学习路线传送门: Docker学习之路01:Docker的安装 Docker学习之路02:阿里云镜像加速器 Docker学习之路03:Do ...

  7. 创建镜像 - 创建与定制 mysql 镜像

    创建镜像 - 创建与定制 mysql 镜像 本文通过制作与定制 mysql 镜像为案例,一方面说明创建镜像简单,另一方面解释 docker image 的内容,直观描述 docker build 命令 ...

  8. Docker运维教程(5)本地镜像制作与dockerfile

    虽然Docker仓库中提供了大量镜像,但是当我们找不到现成镜像或者需要在镜像中满足特定功能时,就需要自己来制作一套镜像.Docker提供了三种制作镜像的方式:docker save/load.dock ...

  9. Ghost镜像与wim镜像

    文章出自:http://mtoou.info/tag/ghost/ Ghost装系统兴起于windowsXP时代,当时由于Ghost安装winXP有着明显快于windows直接安装的速度所以很受青睐, ...

  10. 用标准 GHOST镜像xpe系统(EWF保护模式为RAM)时,写保护丢失问题的解决方法

    在开发具有写保护功能的XPE操作系统时,比较常用的EWF保护模式有RAM模式,特别是针对CF卡,RAM模式能够非常有效的保护CF卡不受FBA频繁的写擦损耗(当然这种CF卡 必须是可以分区的),但是问题 ...

最新文章

  1. 照相机模型与增强现实(相机标定)
  2. 报错解决 :Couldn't find any package by regex 'g++-8'
  3. SpringBoot使用JdbcTemplate案例(学习笔记)
  4. 反转链表—leetcode206
  5. 高并发网络架构解决方案分析
  6. “理了么”app使用体验
  7. Spark SQL join的三种实现方式
  8. opencv-api warpPerspective
  9. 如何正确使用开源项目?
  10. ubuntu下Qt cannot find -lGL错误的解决方法
  11. 示波器学习笔记(2)——模拟示波器
  12. Live2D 博客页面添加板娘
  13. 微信视频号下载短视频的步骤
  14. Error during job, obtaining debugging information...
  15. linux操作系统2试题,linux操作系统试题
  16. 高速接口之VGA接口
  17. 【数据结构】物流运输(最短路DP)
  18. VMware 虚拟机的三种网络连接方式
  19. Java IO基础总结
  20. 《SEO实战密码》笔记①-了解搜索引擎

热门文章

  1. CISP 考试教材《第 2 章 知识域:网络安全监管》知识整理
  2. JAVA常量池,一篇文章就足够入门了。(含图解)
  3. 3个方法教你怎么避免拼多多比价订单
  4. 输出100以内的素数
  5. VUE前端+Node后台模拟打印机Web即时打印
  6. 程序员跳槽时,如何高效地准备面试?
  7. 软件工程实践 Blog17
  8. 整车EMC正向开发及仿真
  9. 4个可以下载IEEE论文、计算机论文的网站
  10. ubuntu中fcitx输入法不显示拼音与候选词框