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

使用garygrossgarten/github-action-ssh遇Docker非TTY设备登录错误求助

问题解决方案

错误原因分析

  1. 环境变量未传递到远程机器:SSH命令里使用的$DOCKER_TOKEN、$USERNAME等是GitHub Actions的环境变量,但远程服务器不存在这些变量,导致docker login因缺少有效凭证触发交互登录(非TTY环境不允许),同时镜像引用因变量未替换出现格式错误。
  2. 容器运行方式问题:未指定后台运行参数,SSH会话结束后容器会直接停止;且未处理旧容器端口冲突的情况。

修改后的Workflow配置

name: Node.js CI

on:
  pull_request:
    branches: ['main']

env:
  REGISTRY: 'ghcr.io/testing/api-gateway'
  # 使用短哈希简化镜像标签,避免潜在格式问题
  IMAGE_NAME: ${{ format('{0}-{1}', github.event.repository.name, github.sha[:7]) }}
  USERNAME: ${{ secrets.USERNAME }}
  DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]

    steps:
      - uses: actions/checkout@v3

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm install
      - run: npm run build

      - name: Build & Push docker
        run: docker build -t $REGISTRY:$IMAGE_NAME .

      - name: Login to github package repository
        run: echo $DOCKER_TOKEN | docker login ghcr.io -u $USERNAME --password-stdin

      - name: Push docker image
        run: docker push $REGISTRY:$IMAGE_NAME

  deploy:
    runs-on: ubuntu-latest
    needs: build

    steps:
      - name: Deploy to Digital Ocean droplet via SSH action
        uses: garygrossgarten/github-action-ssh@release
        with:
          host: ${{ secrets.DO_HOST }}
          username: ${{ secrets.DO_USER }}
          privateKey: ${{ secrets.DO_KEY }}
          passphrase: ${{ secrets.DO_PASSPHRASE }}
          command: |
            # 直接注入GitHub Actions环境变量值到远程命令
            echo "${{ env.DOCKER_TOKEN }}" | docker login ghcr.io -u "${{ env.USERNAME }}" --password-stdin
            docker pull "${{ env.REGISTRY }}:${{ env.IMAGE_NAME }}"
            # 处理旧容器:停止并删除(不存在则忽略错误)
            docker stop api-gateway || true
            docker rm api-gateway || true
            # 后台运行新容器,指定容器名避免冲突
            docker run -d --name api-gateway -p 3000:3000 "${{ env.REGISTRY }}:${{ env.IMAGE_NAME }}"

关键修改点

  • 直接注入变量值:用${{ env.VAR_NAME }}将GitHub Actions的环境变量直接替换到SSH命令中,确保远程服务器能拿到正确的凭证和镜像地址。
  • 容器生命周期管理:添加停止、删除旧容器的命令(|| true避免容器不存在时报错),使用-d参数让容器后台运行,防止SSH会话结束后容器停止。
  • 引号包裹变量:用双引号包裹镜像地址等变量,避免特殊字符导致命令解析错误。
  • 简化镜像标签:使用提交哈希的前7位作为标签后缀,让标签更简洁且避免潜在格式问题。

内容的提问来源于stack exchange,提问作者Sathya Molagoda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:42:24