gitlab-runner 不在 Dockerfile 中运行 ENTRYPOINT 脚本
Posted
技术标签:
【中文标题】gitlab-runner 不在 Dockerfile 中运行 ENTRYPOINT 脚本【英文标题】:gitlab-runner doesn't run ENTRYPOINT scripts in Dockerfile 【发布时间】:2022-01-20 21:26:15 【问题描述】:我在我的项目中使用 gitlab-ci。我已经为 gitlab 容器注册表创建了一个 image
和 push
。
为了创建一个图像并将其注册到gitlab container registry
,我创建了一个Dockerfile
。 Dockerfile:
...
ENTRYPOINT [ "scripts/entry-gitlab-ci.sh" ]
CMD "app"
...
entry-gitlab-ci.sh:
#!/bin/bash
set -e
if [[ $@ == 'app' ]]; then
echo "Initialize image"
rake db:drop
rake db:create
rake db:migrate
fi
exec "$@"
图像将被成功创建,但是当 gitlab-runner 拉取并执行创建的图像时,不会运行 **entry-gitlab-ci** 脚本。
问题是什么?
【问题讨论】:
当你在 GitLab CI 中运行这个图像时会发生什么?您观察到什么行为,是否有错误?你期待什么行为?我不希望在 gitlab CI 中运行时你的“if”条件会被捕获。能否提供一个可复现的 dockerfile 和作业配置? 我希望在 gitlab-runner 拉取图像并运行它时打印“初始化图像”。并且“如果”条件正常。 您将图像用于您的工作还是作为服务?如果您将它用作工作的image:
,则您将无法捕获if
条件,因为GitLab 会覆盖提供给容器的命令。
【参考方案1】:
根据我的经验和努力,我无法让 Gitlab 自动使用 EXEC。与尝试让登录 shell 轻松获取环境变量相同。相反,您必须从 CI 手动运行它。
# .gitlab-ci.yml
build:
image: your-image-name
stage: build
script:
- /bin/bash ./scripts/entry-gitlab-ci.sh
【讨论】:
【参考方案2】:图像入口点肯定会在 GitLab CI 中使用 docker 执行器运行,用于服务和作业,只要它没有被作业配置覆盖。
如果您尝试在您的工作 image:
中使用此图像,则会遇到两个关键问题。
-
GitLab 覆盖图像的命令。所以你的
if
条件永远不会在这里。
您的入口点应该准备好运行 shell 脚本。因此,您应该使用 exec /bin/bash
而不是 exec "$@"
之类的东西作为工作图像。
根据文档:
运行程序期望图像没有入口点,或者入口点已准备好启动 shell 命令。
所以你的入口点可能看起来像这样:
#!/usr/bin/env bash
# gitlab-entrypoint-script
echo "doing something before running commands"
if [[ -n "$CI" ]]; then
echo "this block will only execute in a CI environment"
echo "now running script commands"
# this is how GitLab expects your entrypoint to end, if provided
# will execute scripts from stdin
exec /bin/bash
else
echo "Not in CI. Running the image normally"
exec "$@"
fi
这假设您使用的是 docker 执行程序并且运行程序使用的是 docker >= 17.06 的版本
您还可以在job config image:
中明确设置作业图像和服务图像的入口点。这可能很有用,例如,如果您的图像通常有一个入口点,并且您不想在考虑 GitLab-CI 的情况下构建您的图像,或者如果您想使用具有不兼容入口点的公共图像。
【讨论】:
以上是关于gitlab-runner 不在 Dockerfile 中运行 ENTRYPOINT 脚本的主要内容,如果未能解决你的问题,请参考以下文章