#!/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\""