如何在GitHub Action中调用前序步骤启动的Docker容器执行命令?
GitHub Action中Docker容器复用与测试命令执行问题解决
问题场景
我在构建GitHub Action工作流时,希望启动WildFly Docker容器后,执行Python脚本向容器发送HTTP请求做集成测试,但推送代码后发现Docker镜像构建成功,后续的Python脚本步骤始终无法执行,推测是因为WildFly容器一直处于运行状态,导致前序步骤无法结束。
原工作流配置:
on: [push] jobs: ci_test_job: runs-on: ubuntu-latest name: CI Test steps: - name: Start Wildfly container for integration test id: start-wildfly uses: user/dict/ci-test@master - name: Run Python script run: python3 -m unittest discover -s uat/
对应的自定义Action配置:
name: 'Continuous Integration Test' description: 'Docker Container used for integration test' runs: using: 'docker' image: 'Dockerfile'
Dockerfile代码:
FROM jboss/wildfly:latest RUN wildfly/bin/add-user.sh -u admin -p admin --silent ENTRYPOINT ["/opt/jboss/wildfly/bin/standalone.sh", "-c", "standalone.xml", "-Djboss.http.port=8080", "-Djboss.management.http.port=9998", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
问题原因
使用docker类型的自定义Action时,容器会以ENTRYPOINT指定的命令启动,而WildFly的启动命令是长期运行的进程,会导致该步骤一直处于阻塞状态,永远不会结束,后续的Python脚本步骤自然无法执行。同时,这种方式启动的容器和后续步骤不在同一个环境上下文,即使步骤能结束,后续步骤也无法直接访问容器。
解决方案
方案一:直接在工作流中用Docker命令后台启动容器
放弃自定义Docker Action,直接在工作流步骤中通过docker命令后台启动容器,完成测试后再清理容器,具体配置如下:
on: [push] jobs: ci_test_job: runs-on: ubuntu-latest name: CI Test steps: - name: 拉取代码 uses: actions/checkout@v4 - name: 构建WildFly测试镜像 run: docker build -t wildfly-test . - name: 后台启动WildFly容器 run: docker run -d -p 8080:8080 -p 9998:9998 --name wildfly-test-container wildfly-test - name: 等待WildFly服务就绪 run: | until curl -s http://localhost:8080 > /dev/null; do echo "等待WildFly启动..." sleep 5 done - name: 执行Python测试脚本 run: python3 -m unittest discover -s uat/ - name: 停止并清理容器 run: docker stop wildfly-test-container && docker rm wildfly-test-container
关键说明:
- 使用
docker run -d参数让容器在后台运行,避免阻塞步骤 - 添加等待步骤,确保WildFly服务完全启动后再执行测试(避免因服务未就绪导致测试失败)
- 测试完成后显式停止并删除容器,清理环境
方案二:修改自定义Action为复合Action(可选)
如果想保留自定义Action的结构,可以将其改为复合Action,在Action内部后台启动容器,然后让步骤结束,后续步骤复用容器:
自定义Action的action.yml修改为:
name: 'Continuous Integration Test' description: 'Docker Container used for integration test' runs: using: 'composite' steps: - name: Build WildFly image run: docker build -t wildfly-test . shell: bash - name: Start WildFly container run: docker run -d -p 8080:8080 -p 9998:9998 --name wildfly-test-container wildfly-test shell: bash - name: Wait for WildFly ready run: | until curl -s http://localhost:8080 > /dev/null; do echo "Waiting for WildFly to start..." sleep 5 done shell: bash
然后工作流中使用该Action:
on: [push] jobs: ci_test_job: runs-on: ubuntu-latest name: CI Test steps: - name: Checkout code uses: actions/checkout@v4 - name: Start Wildfly container for integration test uses: user/dict/ci-test@master - name: Run Python script run: python3 -m unittest discover -s uat/ - name: Cleanup container run: docker stop wildfly-test-container && docker rm wildfly-test-container
这种方式将容器启动逻辑封装在复合Action中,同样通过后台启动容器避免步骤阻塞,后续步骤可以直接访问本地端口与容器通信。
内容的提问来源于stack exchange,提问作者Rui
相关产品推荐
相关产品推荐

