放在宿主机
This commit is contained in:
@@ -42,6 +42,11 @@ jobs:
|
|||||||
# 推荐把私钥做成 base64(单行)存到 Secrets,避免多行变量丢换行
|
# 推荐把私钥做成 base64(单行)存到 Secrets,避免多行变量丢换行
|
||||||
SSH_KEY_B64: ${{ github.event.inputs.env == 'dev' && secrets.DEV_SSH_KEY_B64 || secrets.PRO_SSH_KEY_B64 }}
|
SSH_KEY_B64: ${{ github.event.inputs.env == 'dev' && secrets.DEV_SSH_KEY_B64 || secrets.PRO_SSH_KEY_B64 }}
|
||||||
|
|
||||||
|
# Runner 宿主机私钥模式(推荐放宿主机时使用)
|
||||||
|
# - 配置 vars.RUNNER_SSH_KEY_PATH 后将优先使用该私钥文件
|
||||||
|
# - 例:/home/runner/.ssh/deploy_key 或 /root/.ssh/deploy_key
|
||||||
|
RUNNER_SSH_KEY_PATH: ${{ vars.RUNNER_SSH_KEY_PATH }}
|
||||||
|
|
||||||
# Nginx upstream 配置(建议放到 vars)
|
# Nginx upstream 配置(建议放到 vars)
|
||||||
NGINX_UPSTREAM_FILE: ${{ vars.NGINX_UPSTREAM_FILE }}
|
NGINX_UPSTREAM_FILE: ${{ vars.NGINX_UPSTREAM_FILE }}
|
||||||
NGINX_UPSTREAM_NAME: ${{ vars.NGINX_UPSTREAM_NAME }}
|
NGINX_UPSTREAM_NAME: ${{ vars.NGINX_UPSTREAM_NAME }}
|
||||||
@@ -79,40 +84,52 @@ jobs:
|
|||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
chmod 700 ~/.ssh
|
chmod 700 ~/.ssh
|
||||||
|
|
||||||
# 写入私钥
|
# 优先:使用 Runner 宿主机上的私钥文件(避免在 CI 中传输私钥)
|
||||||
if [[ -n "${SSH_KEY_B64:-}" ]]; then
|
SSH_KEY_PATH=""
|
||||||
# 兼容两种常见误配置:
|
if [[ -n "${RUNNER_SSH_KEY_PATH:-}" ]]; then
|
||||||
# 1) *_SSH_KEY_B64 里其实粘贴的是“原始私钥”(包含 -----BEGIN ... PRIVATE KEY-----)
|
SSH_KEY_PATH="${RUNNER_SSH_KEY_PATH}"
|
||||||
# 2) base64 值在粘贴/保存过程中混入空白或其他无关字符
|
if [[ ! -f "${SSH_KEY_PATH}" ]]; then
|
||||||
if printf '%s' "${SSH_KEY_B64}" | grep -qE 'BEGIN[[:space:]].*PRIVATE[[:space:]]KEY'; then
|
echo "未找到 Runner 宿主机私钥文件:${SSH_KEY_PATH}"
|
||||||
echo "提示:检测到 *_SSH_KEY_B64 看起来是原始私钥内容,将按原始私钥写入(建议你改用真正的 base64 单行值)。"
|
echo "请在 Runner 宿主机上放置私钥,并确保该路径对 Runner 执行用户可读。"
|
||||||
printf '%s' "${SSH_KEY_B64}" | tr -d '\r' > ~/.ssh/id_rsa
|
exit 1
|
||||||
else
|
|
||||||
# 去掉粘贴过程中可能混入的空白字符(换行/回车/空格/Tab)
|
|
||||||
CLEAN_B64="$(printf '%s' "${SSH_KEY_B64}" | tr -d '\r\n\t ')"
|
|
||||||
# -i/--ignore-garbage:忽略非 base64 字符,提升兼容性;最终仍会用 ssh-keygen 校验私钥可用性
|
|
||||||
if ! printf '%s' "${CLEAN_B64}" | base64 -d -i | tr -d '\r' > ~/.ssh/id_rsa; then
|
|
||||||
echo "私钥 base64 解码失败:"
|
|
||||||
echo "- 请确认你在 Gitea Secrets 配置的 *_SSH_KEY_B64 是“单行 base64 字符串”,不要带引号/前后空格。"
|
|
||||||
echo "- 推荐用仓库里的脚本生成并复制:node scripts/ssh-key-to-b64.mjs ~/.ssh/你的私钥 --clipboard"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
chmod 600 "${SSH_KEY_PATH}" || true
|
||||||
else
|
else
|
||||||
printf '%s' "${SSH_KEY}" | tr -d '\r' > ~/.ssh/id_rsa
|
# 兜底:从 Secrets 写入私钥(不推荐,但兼容)
|
||||||
|
SSH_KEY_PATH="${HOME}/.ssh/id_rsa"
|
||||||
|
if [[ -n "${SSH_KEY_B64:-}" ]]; then
|
||||||
|
# 兼容两种常见误配置:
|
||||||
|
# 1) *_SSH_KEY_B64 里其实粘贴的是“原始私钥”(包含 -----BEGIN ... PRIVATE KEY-----)
|
||||||
|
# 2) base64 值在粘贴/保存过程中混入空白或其他无关字符
|
||||||
|
if printf '%s' "${SSH_KEY_B64}" | grep -qE 'BEGIN[[:space:]].*PRIVATE[[:space:]]KEY'; then
|
||||||
|
echo "提示:检测到 *_SSH_KEY_B64 看起来是原始私钥内容,将按原始私钥写入(建议你改用真正的 base64 单行值)。"
|
||||||
|
printf '%s' "${SSH_KEY_B64}" | tr -d '\r' > "${SSH_KEY_PATH}"
|
||||||
|
else
|
||||||
|
CLEAN_B64="$(printf '%s' "${SSH_KEY_B64}" | tr -d '\r\n\t ')"
|
||||||
|
if ! printf '%s' "${CLEAN_B64}" | base64 -d -i | tr -d '\r' > "${SSH_KEY_PATH}"; then
|
||||||
|
echo "私钥 base64 解码失败:"
|
||||||
|
echo "- 请确认你在 Gitea Secrets 配置的 *_SSH_KEY_B64 是“单行 base64 字符串”,不要带引号/前后空格。"
|
||||||
|
echo "- 推荐用仓库里的脚本生成并复制:node scripts/ssh-key-to-b64.mjs ~/.ssh/你的私钥 --clipboard"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf '%s' "${SSH_KEY}" | tr -d '\r' > "${SSH_KEY_PATH}"
|
||||||
|
fi
|
||||||
|
chmod 600 "${SSH_KEY_PATH}"
|
||||||
fi
|
fi
|
||||||
chmod 600 ~/.ssh/id_rsa
|
|
||||||
|
|
||||||
# 自检(不输出私钥内容,仅输出元信息,方便定位是否写入了错误文件/被截断)
|
# 自检(不输出私钥内容,仅输出元信息,方便定位是否写入了错误文件/被截断)
|
||||||
echo "id_rsa 字节数:$(wc -c < ~/.ssh/id_rsa | tr -d ' ')"
|
echo "SSH_KEY_PATH=${SSH_KEY_PATH}"
|
||||||
echo "id_rsa 首行:$(head -n 1 ~/.ssh/id_rsa | tr -d '\r')"
|
echo "SSH key 字节数:$(wc -c < "${SSH_KEY_PATH}" | tr -d ' ')"
|
||||||
echo "id_rsa 末行:$(tail -n 1 ~/.ssh/id_rsa | tr -d '\r')"
|
echo "SSH key 首行:$(head -n 1 "${SSH_KEY_PATH}" | tr -d '\r')"
|
||||||
|
echo "SSH key 末行:$(tail -n 1 "${SSH_KEY_PATH}" | tr -d '\r')"
|
||||||
if command -v sha256sum >/dev/null 2>&1; then
|
if command -v sha256sum >/dev/null 2>&1; then
|
||||||
echo "id_rsa sha256(前12位):$(sha256sum ~/.ssh/id_rsa | awk '{print substr($1,1,12)}')"
|
echo "SSH key sha256(前12位):$(sha256sum "${SSH_KEY_PATH}" | awk '{print substr($1,1,12)}')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 快速校验私钥是否可解析(不会输出私钥内容)
|
# 快速校验私钥是否可解析(不会输出私钥内容)
|
||||||
if ! ssh-keygen -y -f ~/.ssh/id_rsa >/dev/null 2>~/.ssh/ssh_key_check.err; then
|
if ! ssh-keygen -y -f "${SSH_KEY_PATH}" >/dev/null 2>~/.ssh/ssh_key_check.err; then
|
||||||
echo "SSH 私钥无法解析。下面是 ssh-keygen 的报错(不包含私钥内容):"
|
echo "SSH 私钥无法解析。下面是 ssh-keygen 的报错(不包含私钥内容):"
|
||||||
cat ~/.ssh/ssh_key_check.err || true
|
cat ~/.ssh/ssh_key_check.err || true
|
||||||
echo
|
echo
|
||||||
@@ -125,6 +142,14 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 供后续步骤统一使用
|
||||||
|
if [[ -n "${GITHUB_ENV:-}" ]]; then
|
||||||
|
echo "SSH_KEY_PATH=${SSH_KEY_PATH}" >> "$GITHUB_ENV"
|
||||||
|
fi
|
||||||
|
if [[ -n "${GITEA_ENV:-}" ]]; then
|
||||||
|
echo "SSH_KEY_PATH=${SSH_KEY_PATH}" >> "$GITEA_ENV"
|
||||||
|
fi
|
||||||
|
|
||||||
SSH_PORT="${SSH_PORT:-22}"
|
SSH_PORT="${SSH_PORT:-22}"
|
||||||
if [[ -n "${GITHUB_ENV:-}" ]]; then
|
if [[ -n "${GITHUB_ENV:-}" ]]; then
|
||||||
echo "SSH_PORT=${SSH_PORT}" >> "$GITHUB_ENV"
|
echo "SSH_PORT=${SSH_PORT}" >> "$GITHUB_ENV"
|
||||||
@@ -142,7 +167,7 @@ jobs:
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SSH_PORT="${SSH_PORT:-22}"
|
SSH_PORT="${SSH_PORT:-22}"
|
||||||
ssh -p "${SSH_PORT}" \
|
ssh -p "${SSH_PORT}" \
|
||||||
-i ~/.ssh/id_rsa \
|
-i "${SSH_KEY_PATH}" \
|
||||||
-o StrictHostKeyChecking=yes \
|
-o StrictHostKeyChecking=yes \
|
||||||
-o BatchMode=yes \
|
-o BatchMode=yes \
|
||||||
-o IdentitiesOnly=yes \
|
-o IdentitiesOnly=yes \
|
||||||
@@ -177,7 +202,7 @@ jobs:
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ssh -p "${SSH_PORT}" -i ~/.ssh/id_rsa -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes \
|
ssh -p "${SSH_PORT}" -i "${SSH_KEY_PATH}" -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes \
|
||||||
"${SSH_USER}@${SSH_HOST}" bash -s -- "${DOCKER_TOKEN}" "${DOCKER_USERNAME}" "${REG}" <<'REMOTE'
|
"${SSH_USER}@${SSH_HOST}" bash -s -- "${DOCKER_TOKEN}" "${DOCKER_USERNAME}" "${REG}" <<'REMOTE'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -208,7 +233,7 @@ jobs:
|
|||||||
|
|
||||||
echo "准备部署:${DOCKER_IMAGE}:${DEPLOY_TAG} -> ${DEPLOY_ENV} (${SSH_USER}@${SSH_HOST}:${SSH_PORT})"
|
echo "准备部署:${DOCKER_IMAGE}:${DEPLOY_TAG} -> ${DEPLOY_ENV} (${SSH_USER}@${SSH_HOST}:${SSH_PORT})"
|
||||||
|
|
||||||
ssh -p "${SSH_PORT}" -i ~/.ssh/id_rsa -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes "${SSH_USER}@${SSH_HOST}" bash -s -- \
|
ssh -p "${SSH_PORT}" -i "${SSH_KEY_PATH}" -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes "${SSH_USER}@${SSH_HOST}" bash -s -- \
|
||||||
"${DOCKER_IMAGE}" "${DEPLOY_TAG}" "${NGINX_UPSTREAM_FILE}" "${NGINX_UPSTREAM_NAME}" "${BLUE_PORT}" "${GREEN_PORT}" "${CONTAINER_PORT}" "${HEALTHCHECK_PATH}" "${REMOTE_ENV_FILE:-}" <<'REMOTE'
|
"${DOCKER_IMAGE}" "${DEPLOY_TAG}" "${NGINX_UPSTREAM_FILE}" "${NGINX_UPSTREAM_NAME}" "${BLUE_PORT}" "${GREEN_PORT}" "${CONTAINER_PORT}" "${HEALTHCHECK_PATH}" "${REMOTE_ENV_FILE:-}" <<'REMOTE'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,19 @@ import { spawnSync } from 'node:child_process';
|
|||||||
|
|
||||||
function printHelp() {
|
function printHelp() {
|
||||||
console.log(`用法:
|
console.log(`用法:
|
||||||
node scripts/ssh-key-to-b64.mjs <私钥文件路径> [--clipboard]
|
node scripts/ssh-key-to-b64.mjs <私钥文件路径> [--clipboard] [--stdout]
|
||||||
node scripts/ssh-key-to-b64.mjs - [--clipboard]
|
node scripts/ssh-key-to-b64.mjs - [--clipboard] [--stdout]
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
node scripts/ssh-key-to-b64.mjs ~/.ssh/deploy_key
|
node scripts/ssh-key-to-b64.mjs ~/.ssh/deploy_key
|
||||||
node scripts/ssh-key-to-b64.mjs - --clipboard
|
node scripts/ssh-key-to-b64.mjs - --clipboard
|
||||||
|
node scripts/ssh-key-to-b64.mjs ~/.ssh/deploy_key --clipboard --stdout
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const clipboard = args.includes('--clipboard') || args.includes('-c');
|
const clipboard = args.includes('--clipboard') || args.includes('-c');
|
||||||
|
const forceStdout = args.includes('--stdout');
|
||||||
const help = args.includes('--help') || args.includes('-h');
|
const help = args.includes('--help') || args.includes('-h');
|
||||||
const input = args.find((a) => !a.startsWith('-'));
|
const input = args.find((a) => !a.startsWith('-'));
|
||||||
|
|
||||||
@@ -79,6 +81,9 @@ if (clipboard) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只输出 base64(单行)
|
// 默认:如果使用了 --clipboard,就不再把超长 base64 打到终端(避免影响后续命令输出)。
|
||||||
process.stdout.write(b64);
|
// 如需同时打印,请加 --stdout。
|
||||||
|
if (!clipboard || forceStdout || process.platform !== 'darwin') {
|
||||||
|
process.stdout.write(b64 + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user