도메인 생성 공통 스크립트 추가
This commit is contained in:
@@ -0,0 +1,182 @@
|
|||||||
|
name: 도메인 생성
|
||||||
|
description: nginx-proxy-manager에 프록시 호스트를 등록하고 Let's Encrypt SSL을 적용 (멱등성 보장)
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
npm-host:
|
||||||
|
required: true
|
||||||
|
description: nginx-proxy-manager 주소 (npm-api.conf의 NGINX_IP)
|
||||||
|
npm-port:
|
||||||
|
required: false
|
||||||
|
default: "81"
|
||||||
|
description: nginx-proxy-manager 관리 API 포트 (npm-api.conf의 NGINX_PORT)
|
||||||
|
npm-user:
|
||||||
|
required: true
|
||||||
|
description: NPM 로그인 이메일 (npm-api.conf의 API_USER)
|
||||||
|
npm-password:
|
||||||
|
required: true
|
||||||
|
description: NPM 로그인 비밀번호 (npm-api.conf의 API_PASS)
|
||||||
|
domain:
|
||||||
|
required: true
|
||||||
|
description: 생성할 도메인 (예: app.example.com)
|
||||||
|
forward-host:
|
||||||
|
required: true
|
||||||
|
description: 프록시가 바라볼 대상 호스트/IP
|
||||||
|
forward-port:
|
||||||
|
required: true
|
||||||
|
description: 프록시가 바라볼 대상 포트
|
||||||
|
websockets:
|
||||||
|
required: false
|
||||||
|
default: "true"
|
||||||
|
description: 웹소켓 지원 활성화
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
host-id:
|
||||||
|
description: 생성되었거나 이미 존재하는 프록시 호스트 ID
|
||||||
|
value: ${{ steps.create.outputs.host-id }}
|
||||||
|
created:
|
||||||
|
description: 이번 실행에서 새로 생성했으면 true, 이미 있었으면 false
|
||||||
|
value: ${{ steps.create.outputs.created }}
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: jq 설치 확인
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# jq가 이미 있으면 건너뜁니다.
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 패키지 매니저에 따라 jq를 설치합니다.
|
||||||
|
if command -v apt-get >/dev/null 2>&1; then
|
||||||
|
apt-get update && apt-get install -y jq
|
||||||
|
elif command -v apk >/dev/null 2>&1; then
|
||||||
|
apk add --no-cache jq
|
||||||
|
elif command -v yum >/dev/null 2>&1; then
|
||||||
|
yum install -y jq
|
||||||
|
else
|
||||||
|
echo "jq 설치 실패: 지원하지 않는 러너 이미지"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 프록시 호스트 생성
|
||||||
|
id: create
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
NPM_HOST: ${{ inputs.npm-host }}
|
||||||
|
NPM_PORT: ${{ inputs.npm-port }}
|
||||||
|
NPM_USER: ${{ inputs.npm-user }}
|
||||||
|
NPM_PASS: ${{ inputs.npm-password }}
|
||||||
|
DOMAIN: ${{ inputs.domain }}
|
||||||
|
FORWARD_HOST: ${{ inputs.forward-host }}
|
||||||
|
FORWARD_PORT: ${{ inputs.forward-port }}
|
||||||
|
WEBSOCKETS: ${{ inputs.websockets }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# 개발서버 전용 고정값
|
||||||
|
BASE="http://${NPM_HOST}:${NPM_PORT}/api" # NPM_SCHEME=http 고정
|
||||||
|
FORWARD_SCHEME="http" # 대상 프로토콜 http 고정
|
||||||
|
EMAIL="$NPM_USER" # Let's Encrypt 이메일 = NPM 계정
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 1. 토큰 발급 (로그인)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
TOKEN=$(curl -fsS -X POST "${BASE}/tokens" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$(jq -nc --arg i "$NPM_USER" --arg s "$NPM_PASS" \
|
||||||
|
'{identity:$i, secret:$s}')" \
|
||||||
|
| jq -r '.token')
|
||||||
|
|
||||||
|
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
||||||
|
echo "NPM 토큰 발급 실패: 자격증명을 확인하세요"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
AUTH="Authorization: Bearer ${TOKEN}"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2. 도메인 중복 체크 (2번째 실행 대응)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
HOST_ID=$(curl -fsS "${BASE}/nginx/proxy-hosts" -H "$AUTH" \
|
||||||
|
| jq -r --arg d "$DOMAIN" \
|
||||||
|
'map(select(.domain_names | index($d))) | .[0].id // empty')
|
||||||
|
|
||||||
|
if [ -n "$HOST_ID" ]; then
|
||||||
|
echo "이미 존재하는 도메인입니다: ${DOMAIN} (host id=${HOST_ID})"
|
||||||
|
echo "host-id=${HOST_ID}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "created=false" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 3. Let's Encrypt 인증서 발급 — 인증서도 멱등 처리
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 같은 도메인의 기존 인증서가 있으면 재사용합니다.
|
||||||
|
CERT_ID=$(curl -fsS "${BASE}/nginx/certificates" -H "$AUTH" \
|
||||||
|
| jq -r --arg d "$DOMAIN" \
|
||||||
|
'map(select(.provider=="letsencrypt" and (.domain_names | index($d)))) | .[0].id // empty')
|
||||||
|
|
||||||
|
if [ -z "$CERT_ID" ]; then
|
||||||
|
echo "Let's Encrypt 인증서 발급 중: ${DOMAIN}"
|
||||||
|
CERT_ID=$(curl -fsS -X POST "${BASE}/nginx/certificates" \
|
||||||
|
-H "$AUTH" -H "Content-Type: application/json" \
|
||||||
|
-d "$(jq -nc --arg d "$DOMAIN" --arg e "$EMAIL" \
|
||||||
|
'{provider:"letsencrypt",
|
||||||
|
domain_names:[$d],
|
||||||
|
meta:{letsencrypt_email:$e, letsencrypt_agree:true, dns_challenge:false}}')" \
|
||||||
|
| jq -r '.id')
|
||||||
|
|
||||||
|
if [ -z "$CERT_ID" ] || [ "$CERT_ID" = "null" ]; then
|
||||||
|
echo "인증서 발급 실패: ${DOMAIN} (도메인 DNS가 NPM을 가리키는지 확인하세요)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "기존 인증서 재사용: ${DOMAIN} (cert id=${CERT_ID})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 4. 프록시 호스트 생성 (SSL 강제 + HTTP/2 고정 적용)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
echo "프록시 호스트 생성 중: ${DOMAIN} -> ${FORWARD_SCHEME}://${FORWARD_HOST}:${FORWARD_PORT}"
|
||||||
|
|
||||||
|
WS=$([ "$WEBSOCKETS" = "true" ] && echo true || echo false)
|
||||||
|
|
||||||
|
PAYLOAD=$(jq -nc \
|
||||||
|
--arg d "$DOMAIN" \
|
||||||
|
--arg fh "$FORWARD_HOST" \
|
||||||
|
--arg fp "$FORWARD_PORT" \
|
||||||
|
--arg fs "$FORWARD_SCHEME" \
|
||||||
|
--argjson cert "$CERT_ID" \
|
||||||
|
--argjson ws "$WS" \
|
||||||
|
'{domain_names:[$d],
|
||||||
|
forward_host:$fh,
|
||||||
|
forward_port:($fp|tonumber),
|
||||||
|
forward_scheme:$fs,
|
||||||
|
certificate_id:$cert,
|
||||||
|
ssl_forced:true,
|
||||||
|
http2_support:true,
|
||||||
|
hsts_enabled:false,
|
||||||
|
hsts_subdomains:false,
|
||||||
|
caching_enabled:false,
|
||||||
|
allow_websocket_upgrade:$ws,
|
||||||
|
block_exploits:true,
|
||||||
|
access_list_id:0,
|
||||||
|
advanced_config:"",
|
||||||
|
locations:[],
|
||||||
|
meta:{}}')
|
||||||
|
|
||||||
|
HOST_ID=$(curl -fsS -X POST "${BASE}/nginx/proxy-hosts" \
|
||||||
|
-H "$AUTH" -H "Content-Type: application/json" \
|
||||||
|
-d "$PAYLOAD" | jq -r '.id')
|
||||||
|
|
||||||
|
if [ -z "$HOST_ID" ] || [ "$HOST_ID" = "null" ]; then
|
||||||
|
echo "프록시 호스트 생성 실패: ${DOMAIN}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "도메인 생성 완료: ${DOMAIN} (host id=${HOST_ID})"
|
||||||
|
echo "host-id=${HOST_ID}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "created=true" >> "$GITHUB_OUTPUT"
|
||||||
Reference in New Issue
Block a user