diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 161f02a..7dbadad 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Deploy to NAS (rsync) +name: Deploy to Ubuntu Server on: push: @@ -8,107 +8,29 @@ on: 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 + - name: Deploy via SSH + env: + HOST: ${{ secrets.NAS_HOST }} + PORT: ${{ secrets.NAS_PORT }} + USER: ${{ secrets.NAS_USER }} 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 + ssh -o StrictHostKeyChecking=no -p $PORT $USER@$HOST << 'EOF' + sudo mkdir -p /opt/robeing-nginx - # 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" + if [ -d "/opt/robeing-nginx/.git" ]; then + cd /opt/robeing-nginx && git pull origin main + else + git clone https://github.com/ivada-Robeing/nginx-deploy.git /opt/robeing-nginx + cd /opt/robeing-nginx 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 + sudo mkdir -p ssl certbot-webroot + sudo docker-compose down || true + sudo docker-compose up -d EOF \ No newline at end of file diff --git a/README.md b/README.md index 91e175b..b7cea4a 100644 --- a/README.md +++ b/README.md @@ -53,11 +53,14 @@ docker-compose -f docker-compose.yml up -d ## 서비스 구성 - **nginx**: 리버스 프록시 (포트 80, 443) -- **api-base**: API 서버 (포트 8000) -- **test_api**: 테스트 API 서버 (포트 8001) -- **frontend**: 프론트엔드 서버 (포트 5173) -- **postgres**: PostgreSQL 데이터베이스 -- **redis**: Redis 캐시 +- **frontend/backend**: 통합 서버 (포트 18000) +- **api_base**: API 서버 (포트 8001) + +## 프록시 라우팅 + +- `https://ro-being.com/` → 192.168.219.45:5173 (메인 프론트엔드) +- `https://ro-being.com/api/` → 192.168.219.45:18000 (frontend/backend) +- `https://ro-being.com/rb8001/` → 192.168.219.45:8001 (api_base) ## Health Check diff --git a/default.conf b/default.conf index 0a4ec7a..8e9b61d 100644 --- a/default.conf +++ b/default.conf @@ -1,10 +1,53 @@ +# HTTP to HTTPS redirect server { listen 80; - + server_name ro-being.com; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { - proxy_pass http://127.0.0.1:5137; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + return 301 https://$server_name$request_uri; + } +} + +# HTTPS server +server { + listen 443 ssl; + server_name ro-being.com; + + ssl_certificate /etc/nginx/ssl/live/ro-being.com/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/live/ro-being.com/privkey.pem; + + # SSL settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # Main application proxy + location / { + proxy_pass http://192.168.219.45:5173; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # API endpoints + location /api/ { + proxy_pass http://192.168.219.45:18000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # RB8001 API endpoints + location /rb8001/ { + proxy_pass http://192.168.219.45:8001; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; } } \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 32c92b1..787bc9c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,18 @@ services: image: nginx:alpine ports: - "80:80" + - "443:443" volumes: - ./default.conf:/etc/nginx/conf.d/default.conf:ro - restart: always \ No newline at end of file + - ./ssl:/etc/nginx/ssl:ro + restart: always + depends_on: + - certbot + + certbot: + image: certbot/certbot:latest + volumes: + - ./ssl:/etc/letsencrypt + - ./certbot-webroot:/var/www/certbot + command: certonly --webroot --webroot-path=/var/www/certbot --email admin@ro-being.com --agree-tos --no-eff-email -d ro-being.com + restart: "no" \ No newline at end of file