#!/usr/bin/env node const { execSync } = require("child_process"); const fs = require("fs"); const path = require("path"); const isWin = process.platform === "win32"; const projectName = "saju-web"; const projectRoot = path.resolve(__dirname, ".."); // SSH μ„€μ • const sshTarget = process.env.NAS_SSH_TARGET || "bgg8988@192.168.45.54"; const sshPath = process.env.NAS_SSH_PATH || `/volume1/docker/webpage/${projectName}`; const sshPort = process.env.NAS_SSH_PORT || "2300"; console.log("πŸš€ Saju Web NAS Deployment (SCP Mode)"); console.log("====================================="); console.log(`Target: ${sshTarget}:${sshPath}`); console.log(""); try { const sshCmd = sshPort ? `ssh -p ${sshPort}` : "ssh"; const scpCmd = sshPort ? `scp -P ${sshPort}` : "scp"; // 1. NAS에 디렉토리 생성 console.log("πŸ“¦ Step 1: Preparing NAS directory..."); execSync(`${sshCmd} ${sshTarget} "mkdir -p ${sshPath}"`, { stdio: "inherit", }); console.log("βœ… Directory ready"); console.log(""); // 2. 파일 전솑 (tar + ssh pipe) console.log("πŸ“€ Step 2: Transferring files to NAS..."); const excludeArgs = [ "--exclude=node_modules", "--exclude=.next", "--exclude=.git", "--exclude=dist", "--exclude=out", "--exclude=.env.local", "--exclude=*.log", "--exclude=saju-web-deploy.tar.gz", ].join(" "); // tar둜 μ••μΆ•ν•˜λ©΄μ„œ λ™μ‹œμ— ssh둜 전솑 const transferCmd = `tar -czf - ${excludeArgs} . | ${sshCmd} ${sshTarget} "cd ${sshPath} && tar -xzf -"`; console.log("Transferring files (this may take a moment)..."); execSync(transferCmd, { cwd: projectRoot, stdio: "inherit", shell: true, }); console.log("βœ… Files transferred"); console.log(""); // 3. NASμ—μ„œ 배포 console.log("πŸ“ Step 3: Deploying on NAS..."); // Docker λͺ…λ Ήμ–΄ 경둜 (Synology NAS) // κΈ°λ³Έκ°’: sudo 없이 μ‹€ν–‰ const dockerCmd = process.env.NAS_USE_SUDO === "true" ? "sudo /usr/local/bin/docker" : "/usr/local/bin/docker"; // ν™˜κ²½ λ³€μˆ˜ μ„€μ • console.log(" - Setting up environment..."); execSync(`${sshCmd} ${sshTarget} "cd ${sshPath} && if [ -f .env.nas ]; then cp -f .env.nas .env; fi"`, { stdio: "inherit", }); // Docker λΉŒλ“œ 및 배포 console.log(" - Building Docker container..."); execSync(`${sshCmd} ${sshTarget} "cd /volume1/docker/webpage && ${dockerCmd} compose build ${projectName}"`, { stdio: "inherit", }); console.log(" - Starting container..."); execSync(`${sshCmd} ${sshTarget} "cd /volume1/docker/webpage && ${dockerCmd} compose up -d ${projectName}"`, { stdio: "inherit", }); console.log("βœ… Deployment complete"); console.log(""); // 5. ν—¬μŠ€μ²΄ν¬ console.log("πŸ₯ Step 4: Health check..."); setTimeout(() => { try { const healthCmd = `${sshCmd} ${sshTarget} "docker exec ${projectName} wget -q -O- http://localhost:3000/api/health"`; const health = execSync(healthCmd, { encoding: "utf-8" }); console.log("Health check response:", health); console.log("βœ… Service is healthy"); } catch (err) { console.warn("⚠️ Health check failed (service may still be starting)"); } console.log(""); console.log("πŸŽ‰ Deployment completed!"); console.log("====================================="); console.log(`🌐 Access: http://gahusb.synology.me/saju`); console.log(""); }, 3000); } catch (err) { console.error("❌ Deployment failed:", err.message); // μ—λŸ¬ λ°œμƒ μ‹œ μž„μ‹œ 파일 정리 const archivePath = path.join(projectRoot, "saju-web-deploy.tar.gz"); if (fs.existsSync(archivePath)) { fs.unlinkSync(archivePath); } process.exit(1); }