GitHub工作流中Docker容器与本地Docker CLI运行不一致问题
问题描述
我在GitHub工作流中运行一个简单的salt master容器,本地用docker run命令运行镜像完全正常——能连接4505、4506端口,Dockerfile定义的ENTRYPOINT也正常工作,但在GitHub工作流环境里容器无法监听并响应请求。
Dockerfile内容
FROM debian:bookworm ARG salt_version ENV SALT_VERSION $salt_version ENV DEBIAN_FRONTEND noninteractive # Install salt RUN echo "salt_version = $SALT_VERSION" RUN apt-get -qq update && \ apt-get -qq upgrade -y && \ apt-get install -y curl ssh RUN mkdir -p /etc/apt/keyrings && \ mkdir -p /srv/dev/salt/salt_states && \ mkdir -p /srv/dev/salt/salt_pillars && \ curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public -o /etc/apt/keyrings/salt-archive-keyring.pgp && \ curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources && \ apt-get update && \ apt-get install -y salt-cloud=$SALT_VERSION && \ apt-get install -y salt-master=$SALT_VERSION && \ salt-call --local pip.install ipy && \ salt-call --local pip.install requests ENTRYPOINT /usr/bin/salt-master -l error
GitHub工作流配置
name: Deploy on: [workflow_dispatch] jobs: Provision_applications: runs-on: [self-hosted, linux, x64, docker-ci-runner] container: image: ghcr.io/mycompany/salt-master:latest ports: - 4505:4505 - 4506:4506 credentials: username: ${{ github.actor }} password: ${{ secrets.PAT }} steps: - name: Destroy any existing container run: | hostname -f salt-cloud --version salt-cloud -m /etc/salt/cloud.maps.d/myhost.map -d -y - name: Provision container run: | hostname -f salt-cloud -y -m /etc/salt/cloud.maps.d/myhost.map - name: Deploy application code run: | hostname -f ps faux salt "myhost.lan" test.ping salt-run state.orchestrate orch.srv-compute pillar='{"vm_name": "myhost"}' - name: Destroy created container run: | salt-cloud -m /etc/salt/myhost.map -d -y
出现的问题
- 容器未使用Dockerfile中定义的
ENTRYPOINT(通过docker ps输出确认) - 端口映射未生效,无法通过telnet连接Docker主机的4505/4506端口
本地测试命令
docker run -it -p 4505:4505 -p 4506:4506 ghcr.io/mycompany/salt-master:latest
本地运行该命令可正常telnet到4505或4506端口,但工作流中无法实现。
补充说明
jobs.<job_id>.container中没有entrypoint配置项- 考虑过用
services但不确定是否适配当前场景 - 尝试过用
CMD替代ENTRYPOINT,无效后改回ENTRYPOINT
解决方案
1. 核心问题:GitHub Actions容器模式的运行逻辑
GitHub Actions的container字段是用来作为Job的执行环境,它会强制覆盖镜像的ENTRYPOINT/CMD,转而执行Job的steps命令。这就是为什么你看到ENTRYPOINT没生效的原因——salt-master根本没启动,容器被steps的命令接管了。
2. 调整工作流:手动启动salt-master
在Job的steps开头先启动salt-master后台进程,再执行后续操作:
steps: - name: Start salt-master in background run: | /usr/bin/salt-master -l error & # 等待服务启动完成 sleep 10 # 验证端口监听状态 netstat -tulpn | grep -E "4505|4506" - name: Destroy any existing container run: | hostname -f salt-cloud --version salt-cloud -m /etc/salt/cloud.maps.d/myhost.map -d -y # 后续步骤保持不变...
3. 端口映射问题说明
在GitHub Actions的container模式下,ports字段仅用于让Job内部的容器暴露端口给同一Job的其他服务容器,而非暴露给runner主机。如果你的salt-minion(myhost.lan)在runner主机或外部网络,需要:
- 确认salt-master配置(
/etc/salt/master)中监听地址为0.0.0.0(默认已配置) - 若用自托管runner,可放弃
container字段,改用docker run命令直接映射端口到主机
4. 替代方案:用services启动salt-master
如果希望salt-master作为独立服务运行,改用services字段,它会以独立容器运行并保留镜像的ENTRYPOINT:
jobs: Provision_applications: runs-on: [self-hosted, linux, x64, docker-ci-runner] services: salt-master: image: ghcr.io/mycompany/salt-master:latest ports: - 4505:4505 - 4506:4506 credentials: username: ${{ github.actor }} password: ${{ secrets.PAT }} steps: - name: Destroy any existing container run: | hostname -f salt-cloud --version # 指定salt-master服务的地址 salt-cloud -m /etc/salt/cloud.maps.d/myhost.map -d -y --master=salt-master # 后续所有salt命令都需要添加--master=salt-master参数
关键注意点
container是Job的执行环境,不是用来运行长期服务的,优先执行steps命令services才是运行辅助服务的正确方式,会保留镜像的ENTRYPOINT/CMD- 自托管runner需确保docker网络配置允许容器间、容器与外部的通信
内容的提问来源于stack exchange,提问作者Pier
相关产品推荐
相关产品推荐

