mirror of
				https://github.com/appleboy/scp-action.git
				synced 2025-10-23 08:55:54 +08:00 
			
		
		
		
	- Add a v1 version badge for the stable workflow to all README files Signed-off-by: appleboy <appleboy.tw@gmail.com>
		
			
				
	
	
	
		
			12 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			12 KiB
		
	
	
	
	
	
	
	
🚀 GitHub Actions 的 SCP
GitHub Action 用於透過 SSH 複製檔案與產物。
注意: 只支援 Linux docker 容器。
✨ 功能特色
- ✅ 透過 SSH 將檔案與產物複製到一台或多台遠端伺服器
- ✅ 支援 SSH 金鑰與密碼驗證
- ✅ 完整支援 SSH Proxy(跳板機)
- ✅ 處理 Linux ↔ Windows 路徑轉換
- ✅ 整合 GitHub Artifacts 工作流程
- ✅ 支援增量與差異檔案傳輸
- ✅ 豐富的進階設定選項
📦 目錄
🚀 快速開始
在 GitHub Actions 工作流程中透過 SSH 複製檔案與產物:
name: scp files
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: 透過 SSH 複製檔案
        uses: appleboy/scp-action@v1
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          source: "tests/a.txt,tests/b.txt"
          target: your_server_target_folder_path
⚙️ 設定說明
🔌 連線設定
| 變數 | 說明 | 預設值 | 必填 | 
|---|---|---|---|
| host | 遠端主機(多台以逗號分隔) | - | ✓ | 
| port | SSH 連接埠 | 22 | |
| username | SSH 使用者名稱 | - | ✓ | 
| password | SSH 密碼(建議使用金鑰以提升安全性) | - | |
| key | SSH 私鑰內容 | - | |
| key_path | SSH 私鑰檔案路徑 | - | |
| passphrase | SSH 私鑰密碼 | - | |
| fingerprint | 主機金鑰 SHA256 指紋驗證 | - | |
| protocol | IP 協定:'tcp'、'tcp4' 或 'tcp6' | tcp | |
| timeout | SSH 連線逾時 | 30s | |
| command_timeout | SCP 指令逾時 | 10m | 
📁 檔案傳輸設定
| 變數 | 說明 | 預設值 | 安全性說明 | 
|---|---|---|---|
| source | 本地要傳送的檔案/目錄(逗號分隔) | - | 請使用明確路徑 | 
| target | 遠端目標目錄(必須為目錄) | - | 避免使用根目錄 | 
| rm | 上傳前移除目標目錄 | - | 請小心使用 | 
| strip_components | 傳送時移除前置路徑元素 | - | |
| overwrite | 使用 tar 覆蓋現有檔案 | - | |
| tar_dereference | tar 傳送時跟隨符號連結 | - | |
| tar_tmp_path | 目標端 tar 暫存檔路徑 | - | |
| tar_exec | 目標端 tar 執行檔路徑 | tar | |
| debug | 啟用除錯輸出 | - | |
| curl_insecure | curl 使用 --insecure | false | 不建議 | 
| capture_stdout | 將指令 stdout 作為 action 輸出 | false | |
| version | 指定 drone-scp 版本 | - | 
🌐 Proxy 設定
| 變數 | 說明 | 預設值 | 必填 | 
|---|---|---|---|
| proxy_host | SSH Proxy 主機 | - | |
| proxy_port | SSH Proxy 連接埠 | 22 | |
| proxy_username | SSH Proxy 使用者名稱 | - | |
| proxy_password | SSH Proxy 密碼 | - | |
| proxy_key | SSH Proxy 私鑰內容 | - | |
| proxy_key_path | SSH Proxy 私鑰檔案路徑 | - | |
| proxy_passphrase | SSH Proxy 私鑰密碼 | - | |
| proxy_fingerprint | Proxy 主機 SHA256 指紋驗證 | - | |
| proxy_use_insecure_cipher | 啟用較不安全的 Proxy 加密演算法 | - | |
| proxy_timeout | SSH Proxy 連線逾時 | 30s | 
🛡️ 最佳實踐與安全性
- 建議優先使用 SSH 金鑰驗證,提升安全性。
- 將所有敏感資訊(host、username、password、key)存放於 GitHub Secrets。
- 定期更換部署金鑰(建議每 90 天一次)。
- 限制目標伺服器目錄的寫入權限。
- 啟用主機金鑰指紋驗證以防止中間人攻擊。
- 避免使用 root 帳號登入 SSH。
🖥️ 跨平台注意事項
| 情境 | Linux 伺服器 | Windows 伺服器 | 
|---|---|---|
| 路徑格式 | /path/to/dir | /c/path/to/dir | 
| 必要設定 | 無 | tar_dereference: true | 
| 權限 | 保留 | 可能需手動設定 ACL | 
| Shell | bash (預設) | Git Bash(OpenSSH) | 
🚩 重要提醒:
複製到 Windows 伺服器時:
- 安裝 Git for Windows 並將 OpenSSH 預設 shell 設為 Git Bash
- 使用 Unix 風格目標路徑(如
/c/Users/...)- 啟用
tar_dereference處理符號連結
💡 使用範例
🧩 情境導覽
範例 1:基本 SSH 密碼
- name: 透過 SSH 密碼複製檔案
  uses: appleboy/scp-action@v1
  with:
    host: example.com
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path
範例 2:多台伺服器
- name: 複製到多台伺服器
  uses: appleboy/scp-action@v1
  with:
    host: "foo.com,bar.com"
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path
範例 3:僅傳送變更檔案
- name: 取得變更檔案
  id: changed-files
  uses: tj-actions/changed-files@v35
  with:
    since_last_remote_commit: true
    separator: ","
- name: 複製變更檔案到伺服器
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: ${{ steps.changed-files.outputs.all_changed_files }}
    target: your_server_target_folder_path
範例 4:整合 Artifacts
- uses: actions/upload-artifact@v4
  with:
    name: my-artifact
    path: world.txt
- uses: actions/download-artifact@v4
  with:
    name: my-artifact
    path: distfiles
- name: 複製 artifact 到伺服器
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: distfiles/*
    target: your_server_target_folder_path
範例 5:Windows 伺服器
- name: 複製到 Windows
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    port: 22
    source: "your_source_path"
    target: "/c/path/to/target/"
    tar_dereference: true
    rm: true
🗝️ SSH 金鑰設定
- 
產生 SSH 金鑰(於本地端執行): # RSA ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # ED25519 ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
- 
將公鑰加入伺服器: cat .ssh/id_rsa.pub | ssh user@host 'cat >> .ssh/authorized_keys' # 或 ed25519 cat .ssh/id_ed25519.pub | ssh user@host 'cat >> .ssh/authorized_keys'
- 
將私鑰內容複製到 GitHub Secrets: clip < ~/.ssh/id_rsa # 或 clip < ~/.ssh/id_ed25519
更多細節請參考 SSH 無密碼登入。
OpenSSH 注意事項:
若出現 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey],請確認金鑰演算法支援。
Ubuntu 20.04+ 可於 /etc/ssh/sshd_config 或 /etc/ssh/sshd_config.d/ 加入:
CASignatureAlgorithms +ssh-rsa
或改用 ed25519 金鑰(預設支援)。
🧰 常見錯誤代碼
| 錯誤代碼 | 可能原因 | 解決方式 | 
|---|---|---|
| ECONNREFUSED | 連接埠錯誤/防火牆阻擋 | 檢查連接埠與防火牆設定 | 
| ENOENT | 找不到來源檔案 | 請用絕對路徑或檢查 checkout 步驟 | 
| EAUTH | 驗證失敗 | 檢查金鑰格式與權限(需 PEM 格式) | 
🔄 工作流程圖
sequenceDiagram
    participant G as GitHub Runner
    participant S as Target Server
    G->>S: 建立 SSH 連線
    S-->>G: 驗證憑證
    G->>S: (可選)移除目標目錄
    G->>G: 封存來源檔案
    G->>S: 傳送封存檔
    S->>S: 解壓與處理檔案
    S-->>G: 回傳結果
FAQ 與疑難排解
- 
Q: 為什麼驗證失敗? 
 A: 請檢查 SSH 金鑰格式、權限,以及金鑰是否已加入伺服器。
- 
Q: 如何只複製變更檔案? 
 A: 使用tj-actions/changed-files取得變更檔案並傳給source。
- 
Q: 如何部署到多台伺服器? 
 A:host參數用逗號分隔多台主機,例如:host: "foo.com,bar.com"
- 
Q: 如何複製到 Windows? 
 A: 設定 Git Bash,使用 Unix 風格路徑,並啟用tar_dereference。
📝 授權條款
MIT License