name: Build and Deploy on: push: branches: - main workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest # ⚠️ ต้องตรงกับ Label ของ Runner ใน Gitea Settings (เช่น self-hosted) steps: - name: Deploy to QNAP via SSH uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} password: ${{ secrets.PASSWORD }} port: ${{ secrets.PORT }} timeout: 1200s # 20 minutes total timeout (เพิ่มจาก 15 นาที) command_timeout: 900s # 15 minutes per command timeout (เพิ่มจาก 10 นาที) script_stop_signal: true # Stop script on error script: | set -e # ⚠️ QNAP SSH ไม่มี PATH เต็ม ต้อง export เอง # docker: /share/CACHEDEV1_DATA/.qpkg/container-station/bin/docker # git: /opt/bin/git export PATH="/share/CACHEDEV1_DATA/.qpkg/container-station/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:$PATH" echo "🚀 Starting Deployment..." # 1. Update Code echo "📂 Pulling latest code..." cd /share/np-dms/app/source/lcbp3 git fetch origin main git reset --hard origin/main # 2. Build Backend echo "🏗️ Building Backend..." docker build -f backend/Dockerfile -t lcbp3-backend:latest . # 3. Build Frontend echo "🏗️ Building Frontend..." docker build -f frontend/Dockerfile \ --build-arg NEXT_PUBLIC_API_URL=https://backend.np-dms.work/api \ -t lcbp3-frontend:latest . # 4. Update Containers echo "🔄 Updating Containers..." # Sync compose file จาก repo → app directory cp /share/np-dms/app/source/lcbp3/specs/04-Infrastructure-OPS/04-00-docker-compose/docker-compose-app.yml /share/np-dms/app/docker-compose-app.yml cd /share/np-dms/app # ⚠️ ลบ container เดิมที่อาจสร้างจาก Container Station - พยายามหลายวิธี echo "🧹 Cleaning up existing containers..." docker stop backend frontend 2>/dev/null || true sleep 5 docker rm -f backend frontend 2>/dev/null || true sleep 3 # ถ้ายังลบไม่ได้ ลอง force remove ด้วย container ID for container in backend frontend; do if docker ps -a --format "{{.Names}}" | grep -q "^${container}$"; then echo "🔧 Force removing container: $container" container_id=$(docker ps -a --filter "name=$container" --format "{{.ID}}") if [ ! -z "$container_id" ]; then docker rm -f "$container_id" 2>/dev/null || true sleep 2 fi fi done # 4a. Start Backend ก่อน echo "🟢 Starting Backend..." docker compose -f docker-compose-app.yml up -d backend # 4b. รอ Backend healthy (ทุก 30 วิ สูงสุด 180 วิ) echo "⏳ Waiting for Backend health check..." for i in $(seq 1 6); do echo "🔍 Health check attempt $i/6..." health=$(docker inspect --format='{{.State.Health.Status}}' backend 2>/dev/null || echo "starting") echo "📊 Health status: $health" if [ "$health" = "healthy" ]; then echo "✅ Backend is healthy!" break fi if [ "$i" = "6" ]; then echo "⚠️ Backend health check timeout after 180s - checking logs" echo "📋 Backend logs (last 20 lines):" docker logs --tail 20 backend echo "🔧 Starting frontend anyway (backend may still be starting)" fi sleep 30 done # 4c. Start Frontend echo "🟢 Starting Frontend..." docker compose -f docker-compose-app.yml up -d frontend # 5. Cleanup echo "🧹 Cleaning up unused images and containers..." docker image prune -f docker system prune -f --volumes 2>/dev/null || true echo "📊 Final container status:" docker ps -a echo "✅ Deployment Complete!"