Files
Genesis_GameServer/deploy/publish-linux.sh
2026-09-04 01:44:59 +09:00

125 lines
4.2 KiB
Bash

#!/usr/bin/env bash
# 리눅스용 자체 포함 실행 파일을 만들고 서버로 올린다.
# 윈도우(Git Bash)·맥·리눅스 어디서 돌려도 된다. 서버에는 .NET 을 설치할 필요가 없다.
#
# ./deploy/publish-linux.sh # 빌드만
# ./deploy/publish-linux.sh ubuntu@서버 # 빌드 후 업로드까지
#
# 경로·서비스 이름이 다르면 환경변수로 준다:
# REMOTE_DIR=/home/ubuntu/gameserver SERVICE=GameServer # ./deploy/publish-linux.sh ubuntu@서버
#
# 업로드된 사진(wwwroot/uploads)은 건드리지 않는다.
set -euo pipefail
PROJECT="GameServer/GameServer.csproj"
OUT="artifacts/linux-x64"
TARGET="${1-}"
REMOTE_DIR="${REMOTE_DIR:-/srv/genesis}"
# 비우면 서버에서 자동으로 찾는다.
SERVICE="${SERVICE:-}"
echo "== 1) 빌드 =="
rm -rf "$OUT"
dotnet publish "$PROJECT" \
-c Release \
-r linux-x64 \
--self-contained true \
-p:PublishSingleFile=true \
-p:EnableCompressionInSingleFile=true \
-p:DebugType=none \
-p:DebugSymbols=false \
-o "$OUT" \
--nologo
# 개발용 설정은 서버로 보내지 않는다.
rm -f "$OUT/appsettings.Development.json"
# 서버에서 바로 띄울 수 있는 실행 스크립트를 함께 넣는다.
# - ASPNETCORE_URLS 를 지정하지 않으면 localhost:5000 에만 묶여 외부에서 안 보인다.
# - 윈도우에서 복사하면 실행 권한이 사라지므로 여기서 다시 붙인다.
cat > "$OUT/run.sh" <<'RUNSH'
#!/usr/bin/env bash
# 서버에서 이 폴더로 들어와 ./run.sh 하면 바로 뜬다.
# PORT=8080 ./run.sh 처럼 포트를 바꿀 수 있다.
set -euo pipefail
cd "$(dirname "$0")"
PORT="${PORT:-5281}"
chmod +x ./GameServer 2>/dev/null || true
mkdir -p wwwroot/uploads
# 0.0.0.0 이어야 바깥에서 접속된다. 127.0.0.1 로 두면 서버 안에서만 보인다.
export ASPNETCORE_URLS="http://0.0.0.0:${PORT}"
export ASPNETCORE_ENVIRONMENT=Production
# genesis.env 가 있으면 거기 값이 appsettings.json 보다 우선한다.
if [ -f ./genesis.env ]; then
set -a; . ./genesis.env; set +a
fi
echo "http://0.0.0.0:${PORT} 에서 실행합니다. (Ctrl+C 로 종료)"
exec ./GameServer
RUNSH
chmod +x "$OUT/run.sh"
# 배포 후 확인 스크립트도 함께 넣는다.
cp "$(dirname "$0")/healthcheck.sh" "$OUT/" 2>/dev/null || true
chmod +x "$OUT/healthcheck.sh" 2>/dev/null || true
echo
echo " 산출물: $OUT ($(du -sh "$OUT" | cut -f1))"
if [ -z "$TARGET" ]; then
echo
echo " 서버로 올리려면: $0 user@서버주소"
exit 0
fi
echo
echo "== 2) 업로드 =="
echo " 대상: $TARGET:$REMOTE_DIR"
ssh "$TARGET" "mkdir -p '$REMOTE_DIR'"
if command -v rsync >/dev/null 2>&1; then
# rsync 가 있으면 지운 파일까지 맞춰 준다.
# 다만 uploads 와 비밀값 파일은 제외해 서버 것을 남긴다.
rsync -avz --delete --exclude 'wwwroot/uploads/' --exclude 'genesis.env' --exclude 'appsettings.Production.json' "$OUT/" "$TARGET:$REMOTE_DIR/"
else
# 윈도우 Git Bash 에는 보통 rsync 가 없다. scp 로 보낸다.
# scp 는 덮어쓰기만 하고 지우지 않으므로 서버의 사진은 그대로 남는다.
echo " rsync 가 없어 scp 로 보냅니다."
# 산출물에 appsettings.Production.json 이 없으므로 서버 것이 덮어써지지 않는다.
scp -r "$OUT"/* "$TARGET:$REMOTE_DIR/"
fi
echo
echo "== 3) 마무리 =="
# 윈도우에서 복사하면 실행 권한이 사라진다. 서버에서 다시 붙인다.
ssh "$TARGET" "
cd '$REMOTE_DIR' &&
chmod +x GameServer run.sh &&
mkdir -p wwwroot/uploads &&
echo ' 실행 권한 설정 완료'
SVC='$SERVICE'
# 이름을 안 줬으면 이 폴더를 실행하는 서비스를 찾아본다.
if [ -z \"\$SVC\" ]; then
for c in GameServer genesis gameserver portfolio; do
if systemctl list-unit-files 2>/dev/null | grep -q \"^\$c.service\"; then SVC=\$c; break; fi
done
fi
if [ -n \"\$SVC\" ]; then
sudo systemctl restart \"\$SVC\" && echo \" \$SVC 서비스 재시작\"
else
echo ' systemd 서비스를 찾지 못했습니다. ./run.sh 로 직접 실행하세요.'
fi
"
echo
echo "완료."
echo " 바로 띄워 보려면: ssh $TARGET \"cd $REMOTE_DIR && ./run.sh\""