You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:28:17