登录
  • 人们都希望被别人需要 却往往事与愿违
  • 世界上只有两种编程语言: 要么充满了抱怨; 要么没人使用@Bjarne Stroustrup (C++之父)

Docker Hub与submodule踩坑小记

编程 Benny小土豆 3351次浏览 2896字 4个评论
文章目录[显示]

大家都懂,使用 Docker分发应用是非常舒服畅快的事情!通常来说,如果我们在GitHub开源代码,通常也就会选择Docker Hub来构建镜像。当然啦,用GitHub Action,或者自己构建再提交也是一种办法哦。

怎么写Dockerfile,比如不同层级的RUN,正确应用multi stage build,那是另外一个话题啦。今天来说说在为 yyetsweb构建docker image的时候,我踩到的坑……

环境变量

说到环境变量,首先我们要区分一下运行时环境变量和构建时环境变量。

运行时环境变量

我们在Dockerfile中使用 ENV定义的变量就可以算运行时环境变量啦,比如说这样:

ENV TZ=Asia/Shanghai

这个TZ变量会被容器中的程序直接读取使用。

构建时环境变量

在构建时会被读取使用的变量,比如说在Docker Hub会有这样的设置:

Docker Hub与submodule踩坑小记

那么这个变量就是可以在Dockerfile里使用:

RUN echo $REACT_APP_DOMAIN

使用的啦。

我的使用

因为前端的SPA应用要在构建时使用一些环境变量,所以我就在 Docker Hub的设置中加了这几个,但是似乎并没有生效。不知道为什么会这样,考虑到构建时会读取项目根目录下的 .env文件,那不如应用一下Docker Hub的hooks吧!

Docker Hub的build hooks一共有这么几种:

  • hooks/post_checkout
  • hooks/pre_build
  • hooks/post_build
  • hooks/pre_test
  • hooks/post_test
  • hooks/pre_push (only used when executing a build rule or automated build )
  • hooks/post_push (only used when executing a build rule or automated build )

每一个hook都可以包含docker命令和各种bash命令。那对于我的场景来说, 创建一个pre_build就可以啦

#!/bin/bash
cat << EOF >> YYeTsFE/.env
SENTRY_ORG=$SENTRY_ORG
SENTRY_PROJECT=$SENTRY_PROJECT
SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN

REACT_APP_SENTRY_DSN=$REACT_APP_SENTRY_DSN
REACT_APP_DOMAIN=$REACT_APP_DOMAIN
REACT_APP_GA=$REACT_APP_GA
# sourcemap
GENERATE_SOURCEMAP=$GENERATE_SOURCEMAP
EOF

完美!

submodule

使用git submodule继承其他项目是非常理想的一种开发方式。我们可以控制submodule跟踪到上游的哪一个commit,需要更新时只需要一个 git submodule update --remote,然后再把hash commit就可以啦。

Docker Hub在build时会自动clone相应的submodule,因此常规情况下来讲,大部分情况下都是可以顺利构建的。只不过有几点需要注意:

  1. docker hub执行的是shallow copy,因此只有最新的commit和对应的branch会被拉下来,因此如果你的build脚本是依赖了git branch和不同的commit,那会失败的哦。这个时候要用hooks来解决
  2. private submodule需要一些额外设置,可以参考官网文档来解决
  3. 在module里执行git相关的命令,很有可能失败的哦(这可能是Docker Hub的bug,也有可能是git版本的问题)。

我要详细的说下第三点🤣

在我的构建脚本中,我用了git rev-parse --short HEAD 来获取submodule的hash,然后把这个hash作为tag推送到sentry上。但是在构建日志中发现了这种错误:

---> Running in 4c09a0ea3725

yarn run v1.22.5

$ (export REACT_APP_SENTRY_RELEASE=$(git rev-parse --short HEAD); react-scripts build && node scripts/sentry.js)

[91mfatal: not a git repository: /src/bt57w8kzzcjnpmscaemsqqq/.git/modules/YYeTsFE

然而在本地完全是无法复现的,整个目录树如下,我保证Docker Hub在build时也有同样的结构:

$ tree -L 2 -a

|-- .dockerignore
|-- .git
| |-- HEAD
| |-- branches
| |-- config
| |-- description
| |-- hooks
| |-- index
| |-- info
| |-- logs
| |-- modules
| |-- objects
| |-- packed-refs
| `-- refs
|-- .gitattributes
|-- .gitignore
|-- .gitmodules
|-- .travis.yml
|-- Dockerfile
|-- Makefile
|-- README.md
|-- YYeTsFE
| |-- .env.example
| |-- .git
| |-- .gitignore
| |-- .sentryclirc
| |-- README.md
| |-- package.json
| |-- public
| |-- scripts
| |-- src
| |-- tsconfig.json
| `-- yarn.lock

submodule也有.git,项目根目录也有.git,为什么就会失败呢?进行了无数次尝试,让Docker Hub一晚上疯狂构建😂

后来研究了一下,submodule的.git其实是一个到父目录.git/modules/ModuleName的引用。

~/PycharmProjects/YYeTsBot/YYeTsFE (60c497b*) [02:06:51]
benny$ cat .git
gitdir: ../.git/modules/YYeTsFE

然而在 Docker Hub上,这个目录是绝对路径,并且是host的路径🤦‍♂️:

gitdir: /src/brp47ykf7wlmztspk2mtpl8/.git/modules/YYeTsFE

这不报错就怪了。

解决方法也很简单,在hook中改掉.git文件,或者在Dockerfile中改掉,考虑到无法定位到问题究竟是出在Docker Hub还是git,我就选择在Dockerfile中搞啦

RUN echo "gitdir: ../.git/modules/YYeTsFE" > .git

就这么一行代码,花了我两三个小时🌚🌚🤬

参考

Docker Hub build hooks: https://docs.docker.com/docker-hub/builds/advanced/

YYeTsBot: https://github.com/tgbot-collection/YYeTsBot

 


文章版权归原作者所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/dockerhub-submodule.html
喜欢 (28)
分享:-)
关于作者:
If you have any further questions, feel free to contact me in English or Chinese.
发表我的评论
取消评论

                     

去你妹的实名制!

  • 昵称 (必填)
  • 邮箱 (必填,不要邮件提醒可以随便写)
  • 网址 (选填)
(4)个小伙伴在吐槽
  1. 我记得,Docker Hub的自动镜像构建服务好像对免费用户停用了 https://www.docker.com/blog/changes-to-docker-hub-autobuilds/
    神楽坂喵2021-06-28 08:38 回复
    • yes你说的对 https://t.me/mikuri520/929
      --本评论由Telegram Bot回复~❤️
      Benny小土豆2021-06-28 08:39 回复
  2. 疯狂踩坑 :evil:
    醉渔2021-06-19 14:39 回复
    • 是的没错.jpg
      --本评论由Telegram Bot回复~❤️
      Benny小土豆2021-06-19 14:40 回复