- Detect if system service (DSM/Web Station) uses port 80 - Automatically switch nginx to port 8080 if port 80 is occupied - Avoid touching system services, only manage Docker containers - Prevents conflicts with Synology NAS built-in services 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
114 lines
4.2 KiB
YAML
114 lines
4.2 KiB
YAML
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 |