热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从定制Ghost镜像聊聊优化Dockerfile

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

在 《修理 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-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"]

这里存在几个问题:

  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 为例):

  • 确认新旧版本差异: https://github.com/TryGhost/Ghost/compare/3.3.0…3.9.0
    • 老版本需要放在前面,不然按照时间线,是一定对比不出内容的。
  • 确认新版本引用子模块版本: https://github.com/TryGhost/Ghost/tree/3.9.0/core
    .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


以上所述就是小编给大家介绍的《从定制 Ghost 镜像聊聊优化Dockerfile》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • mysql自动打开文件_让docker中的mysql启动时自动执行sql文件
    本文提要本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动My ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了GregorianCalendar类的基本信息,包括它是Calendar的子类,提供了世界上大多数国家使用的标准日历系统。默认情况下,它对应格里高利日历创立时的日期,但可以通过调用setGregorianChange()方法来更改起始日期。同时,文中还提到了GregorianCalendar类为每个日历字段使用的默认值。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • Python中sys模块的功能及用法详解
    本文详细介绍了Python中sys模块的功能及用法,包括对解释器参数和功能的访问、命令行参数列表、字节顺序指示符、编译模块名称等。同时还介绍了sys模块中的新功能和call_tracing函数的用法。推荐学习《Python教程》以深入了解。 ... [详细]
author-avatar
丹丹2502857623
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有