project1:我有一个非常简单的python应用程序,它接受cmd行输入并将其打印出来,仅此而已。我创建了这个 python 应用程序的图像,并将其推送到项目 2 的 gitlab 容器注册中心,如下所示(作为 intenede 工作):
app.py
import sys
#print(sys.argv)
print("Yes I am inside the program")
for file in sys.argv:
print(file)
Dockerfile:
FROM python:3.12.7-alpine
WORKDIR /app
COPY app.py .
ENTRYPOINT ["python","app.py"]
.gitlab-ci.yml(创建映像并将其作为自定义映像推送到 gitlab: 阶段:
build image:
stage: build
image: docker:stable
services:
- name: docker:dind
alias: thedockerhost
variables:
# Tell docker CLI how to talk to Docker daemon; see
# https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor
DOCKER_HOST: tcp://thedockerhost:2375/
# Use the overlayfs driver for improved performance:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
script:
# Download bash:
- apk add --no-cache bash python3
- echo "$CI_REGISTRY_USER"
- echo "$CI_REGISTRY_PASSWORD"
- docker login -u <user> -p <password> gitlab.ilts.com:5050
- docker build -t gitlab.ilts.com:5050/group/project2/pythonapp .
- docker push gitlab.ilts.com:5050/group/project2/pythonapp
- docker logout
在 project2 中,我在 GitLab 容器注册表中提供了自定义映像,我尝试使用该映像并提供输入作为文件名。
项目2的.gitlab-ci.yml。
build:
image: gitlab.ilts.com:5050/group/pythonapp:latest
before_script:
- echo "setting environment"
- apk update && apk add git
- git --version
script:
- echo "Creating Tag"
- git switch $CI_COMMIT_REF_NAME
- LAST_VER=$(git tag --list | sort -V | tail -n1)
- echo "$LAST_VER"
- FILES_CHANGED=$(git diff --name-only HEAD v1.0.0)
- echo "$FILES_CHANGED"
- python --version
- python app.py hi.sql yes.sql hello.sql
1)当我执行此操作时,收到的输出对我来说没有意义。您能帮我理解为什么会这样显示吗?我该如何解决它?
输出:
Yes I am inside the program
app.py
sh
-c
if [ -x /usr/local/bin/bash ]; then
exec /usr/local/bin/bash
elif [ -x /usr/bin/bash ]; then
exec /usr/bin/bash
elif [ -x /bin/bash ]; then
exec /bin/bash
elif [ -x /usr/local/bin/sh ]; then
exec /usr/local/bin/sh
elif [ -x /usr/bin/sh ]; then
exec /usr/bin/sh
elif [ -x /bin/sh ]; then
exec /bin/sh
elif [ -x /busybox/sh ]; then
exec /busybox/sh
else
echo shell not found
exit 1
fi
2:是否可以访问此自定义 Python 应用程序映像中的 project2 存储库中的文件进行读写?
问题的根本原因是在 Dockerfile 中使用
ENTRYPOINT
而不是 CMD
。 这两个指令看起来很相似,并且都以某种形式指定要运行的命令。 当您运行容器时,可以单独覆盖它们,并且 docker run
语法使覆盖 CMD
变得更容易。
如果同时提供
ENTRYPOINT
和 CMD
,则 它们将组合成单个命令词列表。 这与您在程序输出中看到的内容相符。
特别是,看起来 GitLab 管道运行容器,用
CMD
内联命令覆盖 ENTRYPOINT
(不是 sh -c 'if [ -x ... ]; ... fi'
)来运行某种 shell,并期望将各个命令输入其中壳。 您的 ENTRYPOINT
只是打印出作为参数传递给它的所有内容,并且实际上并不尝试运行它们。
这里最简单的修复方法是将 Dockerfile 中的
ENTRYPOINT
更改为 CMD
CMD ["./app.py"] # not ENTRYPOINT
如果您确实在这样的设置中使用
ENTRYPOINT
,则需要确保执行其命令行参数才能实际运行CMD
。 我最常编写以 exec "$@"
结尾的 shell 脚本。 您也可以使用 Python 入口点包装器;将以 os.execvp(sys.argv[1], sys.argv[1:])
结束。