discourse_docker 中的浅层 git fetch 回归

您好,

最近一次 docker_discourse 的提交 导致无法在 app.ymlversion: 字段中指定标签(例如 v2.6.0)。这对于 安装旧版本的 Discourse 进行测试非常有用。

当使用提交 e2eb085714dfcf2aa0117b0f2fdf39b762b0e18d 并指定 version: v2.6.0 时,会出现以下问题:

I, [2020-12-05T10:59:38.848743 #1]  INFO -- : > cd /var/www/discourse && git remote set-branches origin v2.6.0
I, [2020-12-05T10:59:38.852600 #1]  INFO -- : 
I, [2020-12-05T10:59:38.852639 #1]  INFO -- : > cd /var/www/discourse && git fetch --depth 1 origin v2.6.0
From https://github.com/discourse/discourse
 * tag                 v2.6.0     -> FETCH_HEAD
I, [2020-12-05T10:59:41.405163 #1]  INFO -- : 
I, [2020-12-05T10:59:41.405307 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
error: pathspec 'v2.6.0' did not match any file(s) known to git
I, [2020-12-05T10:59:41.411796 #1]  INFO -- : 

而在使用该提交之前的那一次提交时,预期的输出如下:

I, [2020-12-05T11:22:14.717910 #1]  INFO -- : > cd /var/www/discourse && git fetch origin v2.6.0
From https://github.com/discourse/discourse
 * tag                     v2.6.0     -> FETCH_HEAD
I, [2020-12-05T11:22:15.672616 #1]  INFO -- : 
I, [2020-12-05T11:22:15.672683 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
Note: checking out 'v2.6.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at d6121249d3 Version bump to v2.6.0
7 个赞

严格来说,这不算是一个 bug,但我们希望能提供一些指南,说明如何安装旧版本的 Discourse,即使这意味着需要使用更复杂的模板或其他方法。

@Falco 正在调查中。

7 个赞

我同意深度应该是可配置的,或许可以通过环境变量实现,默认值为"shallow";但应能通过简单的环境变量进行配置。

1 个赞

我认为这里的问题在于执行 checkout 时本地并不知晓这些标签,类似于以下(与 Discourse 无关)的问题:

运行 git fetch --all 应该能解决这个问题,但我不确定这会增加多少镜像体积(除非后续有其他指令清除了未使用的引用)。

不过,我认为使用 git clone --depth 1 https://github.com/discourse/discourse.git --branch=$version 也能解决问题,因为 branch 参数同时支持分支和标签。但我尚未测试,也不确定目前使用 master 分支进行 clone 是否有特定原因。

执行 git clone --depth 1 https://github.com/discourse/discourse.git --branch=v2.6.0 后,整个文件夹大小为 212MB,其中 .git 文件夹占用 46MB,因此我认为这样是可行的。

这会让仓库体积翻倍:slightly_frowning_face:

问题在于,在构建镜像时,我并不知道你未来想要哪个分支。

当前的设置是为了减小镜像体积而更改的,它使镜像的压缩体积减少了 250MB(25%),这是一个巨大的胜利。在使用 stable、beta 或 tests-passed 等常规分支时,它运行良好。

作为一种变通方法,如果你想切换到某个标签,可以将以下内容应用到你的 app.yml 文件中:

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
+    - exec:
+        cd: $home
+        cmd:
+          - git fetch --depth=1 origin tag v2.5.0 --no-tags
+          - git checkout v2.5.0

另一种变通方法是在 app.yml 的顶层添加一个 base_image 键,其值为较旧的基础镜像。由于我们甚至不尝试保持新镜像能够运行旧版 Discourse 的兼容性,如果你要回退到很旧的版本,这可能是必要的。

9 个赞

你说得对,那时候我们还不知道具体版本。看起来基础镜像使用的是当前版本加上 tests-passed 分支,不过该分支确实包含了镜像构建时的提交记录。

那么,现在的这种方式是否会导致即使使用了 tests-passed 分支,重建速度也会变慢呢?

请考虑以下操作:

在基础镜像中:

git clone --depth 1 https://github.com/discourse/discourse.git
cd discourse/
git remote set-branches --add origin tests-passed

在 web.template.yml 中:

git reset --hard
git clean -f
git remote set-branches --add origin master
git pull
...

当执行 git pull 时,整个仓库都会被拉取,可能需要几分钟,因为之前只进行了浅克隆。你可以在本地尝试运行上述命令来验证。

这并不是说把整个仓库放进基础镜像就更好,但 web.template.yml 中的代码会在每次重建时运行,即使只是在 app.yml 中添加了插件或修改了设置。我通常在我的(非 Discourse)项目中为每个新版本创建新镜像,但这对你来说可能不太可行(考虑到你当前的做法)。

你有没有注意到重建时间有所增加?(或者在大多数情况下,这相对于总重建时间来说并不显著?)

更新

我重新测试了上述步骤,发现速度很快。我想我在第一次尝试时运行了其他指令,改变了 git 树结构,导致在运行 git pull 时试图拉取所有内容。

2 个赞

你确定是这样吗?

➜  discoursesmall git:(6a42acbf) docker run --rm -it discourse/base:2.0.20201125-2246
root@b481d11669ba:/# cd /var/www/discourse/
root@b481d11669ba:/var/www/discourse# du -sh .                                                     
774M    . 
root@b481d11669ba:/var/www/discourse# git pull
...
root@b481d11669ba:/var/www/discourse# du -sh .                                                               
778M    . 
5 个赞

@lucasbasquerotto 你说得对,git pull 确实不是严格必需的,我们已经在 这里 将其移除了。

这样,其他分支(或派生仓库)在未来与 discourse_docker 协作时会更加顺畅 :slight_smile:

5 个赞

是的,我看到它在拉取后会在正确的分支上执行 fetch 和 checkout,所以我认为 git pull 可能不是必需的(不过我还没测试过)。

对于标签,似乎仍需单独 fetch,但这应该是可行的。此外,分支的使用更为普遍,因此标签的使用可能更像是一个边缘情况。

1 个赞

是否可以认为配置文件 standalone.yml 中的 version 选项不起作用?

它仍然有效,但现在只能设置为分支。

3 个赞

我遇到了同样的错误。我之前使用的是 2.5.1 版本。

随后,我遇到了以下错误:

I, [2020-12-31T11:50:24.701475 #1]  INFO -- : > cd /var/www/discourse && find /var/www/discourse ! -user discourse -exec chown discourse {} \+
chown: 无法解析 '/var/www/discourse/public/plugins/styleguide':没有那个文件或目录

重建无法完成。有什么帮助吗?

尝试添加上述键,并使用来自 discourse/base - Docker Image 的较旧镜像。

2 个赞

这不起作用,因为它发生在 因无法检索版本而失败的代码 之后。可行的方法是在 web.template.yml 旁边创建一个名为 version.template.yml 的文件,内容如下:

params:
  home: /var/www/discourse

run:
  - exec:
      cd: $home
      hook: code
      cmd:
        - git fetch --tags

然后在 containers/app.yml 中将该文件包含在 web.template.yml 之前,如下所示:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/version.template.yml"
  - "templates/web.template.yml"

若要使其生效,你不应该在 app.yml 中使用 version 顶级键,只需使用那段新代码即可。这样做就不会失败。

3 个赞

感谢澄清:这正是我之前遗漏的部分。对于和我一样感到困惑的朋友,获取 Discourse 的发布标签可以通过以下步骤实现:

  • 确保 app.yml 中的 version 参数 未设置,例如:
    params:
      db_default_text_search_config: "pg_catalog.english"
      #  version: stable
    
  • app.yml 末尾添加代码以检出所需版本,例如:
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - git clone https://github.com/discourse/docker_manager.git
    +    - exec:
    +        cd: $home
    +        cmd:
    +          - git fetch --depth=1 origin tag v2.5.0 --no-tags
    +          - git checkout v2.5.0
    

运行 ./launcher rebuild app 时,会发生以下情况:

  • 默认 version(即 test_passed 分支)会被检出。
  • v2.5.0 标签会被拉取并检出,从而有效替换之前的版本。
1 个赞

This topic was automatically closed 0 minutes after the last reply. New replies are no longer allowed.