name: Deploy to NAS (rsync) on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup SSH key uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.NAS_SSH_KEY_ADMIN }} - name: Check SSH key loaded run: ssh-add -l - name: Add NAS host to known_hosts run: | mkdir -p ~/.ssh ssh-keyscan -p ${{ secrets.NAS_PORT }} ${{ secrets.NAS_HOST }} >> ~/.ssh/known_hosts - name: Test SSH connection run: | ssh -o StrictHostKeyChecking=no -p ${{ secrets.NAS_PORT }} \ ${{ secrets.NAS_USER }}@${{ secrets.NAS_HOST }} echo "SSH connection successful" - name: Test directory access run: | ssh -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} \ "ls -la /volume1/homes/admin/ && whoami && pwd" - name: Create target directory if not exists run: | ssh -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} \ "mkdir -p /volume1/homes/admin/nginx-infra && ls -la /volume1/homes/admin/nginx-infra" - name: Test rsync availability run: | ssh -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} \ "which rsync && rsync --version" - name: Deploy with file ownership fix run: | tar czf - --exclude='.git' . | ssh -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} \ "mkdir -p /tmp/nginx-infra-deploy && cd /tmp/nginx-infra-deploy && tar xzf - && cp -rf /tmp/nginx-infra-deploy/* /volume1/homes/admin/nginx-infra/ 2>/dev/null || true && rm -rf /tmp/nginx-infra-deploy" - name: Check Docker permissions run: | ssh -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} \ "ls -la /var/run/docker.sock && id" - name: Create deployment archive run: | mkdir -p /tmp/deploy-build tar czf /tmp/deploy-build/deploy.tar.gz --exclude='.git' --exclude='*.tar.gz' --warning=no-file-changed . - name: Copy archive to NAS run: scp -O -o ConnectTimeout=10 -o ServerAliveInterval=60 -P ${{ secrets.NAS_PORT }} /tmp/deploy-build/deploy.tar.gz admin@${{ secrets.NAS_HOST }}:/tmp/ - name: Deploy with atomic swap run: | ssh -o ConnectTimeout=10 -o ServerAliveInterval=60 -p ${{ secrets.NAS_PORT }} admin@${{ secrets.NAS_HOST }} << 'EOF' set -euo pipefail DEPLOY=/volume1/homes/admin/nginx-infra TMPDIR=$(mktemp -d /tmp/deploy.XXXX) BACKUP=${DEPLOY}-backup-$(date +%Y%m%d%H%M%S) # 1) tar로 임시 디렉터리에 풀기 cd "$TMPDIR" && tar xzf /tmp/deploy.tar.gz # 2) 기존 배포물을 백업 if [ -d "$DEPLOY" ]; then mv "$DEPLOY" "$BACKUP" fi # 3) 임시 → 실제 위치로 교체 mv "$TMPDIR" "$DEPLOY" # 4) 오래된 백업 5개만 남기기 ls -1dt ${DEPLOY}-backup-* 2>/dev/null | tail -n +6 | xargs -r rm -rf echo "Deployed to $DEPLOY; backup saved at $BACKUP" # 5) 포트 80 사용 중인 서비스 확인 및 처리 echo "Checking port 80 usage..." netstat -tlnp | grep :80 || true docker ps --format "table {{.Names}}\t{{.Ports}}" | grep ":80" || true # NAS 시스템 서비스가 80포트 사용 중이면 nginx를 8080으로 실행 if netstat -tln | grep -q ":80.*LISTEN"; then echo "Port 80 is used by system service, switching nginx to port 8080" sed -i 's/80:80/8080:80/g' "$DEPLOY/docker-compose.yml" fi # Docker 컨테이너만 정리 (시스템 서비스는 건드리지 않음) docker ps --filter "publish=80" -q | xargs -r docker stop docker ps -a --filter "publish=80" -q | xargs -r docker rm # 6) docker-compose 재시작 cd "$DEPLOY" docker-compose down 2>/dev/null || true docker-compose up -d --build # 6) 임시 파일 정리 rm -f /tmp/deploy.tar.gz EOF