Skip to content

Windows에서 추가 운영 서버 배포 ​

Windows PowerShell에서 사내 Ubuntu 서버 IP로 배포하는 절차입니다. WSL은 사용하지 않습니다. GitHub Actions의 기존 cicd/dev/deploy.sh는 현재 운영 서버 배포에 그대로 사용되며, 이 절차는 추가 서버에 현재 Git 커밋을 전송해 서버에서 빌드합니다. 전체 명령과 파일 전송 예시는 저장소의 deploy/secondary-production/README.md에 있습니다.

서버와 접속 포트 준비 ​

아래 환경파일을 먼저 준비했다면 Windows에서 -Action Install 한 번으로 서버 필수 구성 설치, 빈 DB 초기화와 첫 배포를 이어서 진행할 수 있습니다. PostgreSQL·Redis 비밀번호와 API 포트는 server.env.production의 PGPASSWORD, REDIS_PASSWORD, PORT 값을 그대로 사용합니다. 서버 설치 단계에서 sudo 비밀번호를 물으면 실행한 터미널에 입력합니다. 입력 대기 시간이 지나면 설치가 중단되므로 다시 실행합니다.

powershell
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action Install -ServerIp 10.20.30.40 -SshUser ubuntu -AppHttpPort 8080 -EnvDir $envDir

수동으로 준비하려면 PowerShell의 scp와 ssh로 deploy/secondary-production/install-prereqs.sh를 대상 서버에 전송합니다. 서버에서 다음처럼 실행합니다.

bash
sudo ss -ltnp
sudo APP_USER=ubuntu APP_DIR=/opt/intellidesk-app APP_HTTP_PORT=8080 \
  bash /tmp/install-prereqs.sh

설치 스크립트는 Node.js 22, PM2, PostgreSQL 16, pgvector, Redis와 Nginx를 준비합니다. Ubuntu 24.04와 26.04를 지원하며, ufw가 켜진 서버에서는 앱 포트를 엽니다. 기본 앱 포트는 8080입니다. 80번 포트를 다른 앱이 사용해도 기존 Nginx 사이트를 삭제하지 않으며, 선택한 앱 포트가 이미 사용 중이면 설치 전에 중단합니다. 다른 포트를 쓰려면 APP_HTTP_PORT 값을 바꾸고 아래 접속 URL과 환경파일에도 같은 포트를 사용합니다. API 기본 포트 3001이 사용 중이면 APP_API_PORT와 server.env.production의 PORT를 함께 변경합니다.

새 DB에는 설치용 덤프가 필요하지 않습니다. 첫 배포가 server/database/create_tables_tenant.sql과 server/database/seeds/*.sql을 적용하고, 서버 IP를 호스트로 사용하는 internal 테넌트를 등록합니다. 기존 DB는 다시 초기화하지 않으며, 활성 테넌트의 DB 연결정보와 IP 호스트 매핑이 서버 설정과 다르면 배포가 중단됩니다. 한 IP로 여러 테넌트를 자동 구분할 수 없으므로 이 가이드는 단일 테넌트 구성입니다.

Windows 환경파일 준비 ​

Windows의 %USERPROFILE%\.config\intellidesk-secondary 같은 저장소 외부 폴더에 대상 서버 전용 환경파일 네 개를 준비합니다.

  • client.env.production.
  • server.env.production.
  • intellidesk-agent.env.production.
  • mcp-server.env.production.

서버 IP가 10.20.30.40이고 앱 포트가 8080이면 client.env.production에 VITE_API_URL=/api/v1, server.env.production에 PORT=3001, FRONTEND_URL=http://10.20.30.40:8080, CORS_ALLOWED_ORIGINS=http://10.20.30.40:8080과 새 서버 전용 ENCRYPTION_KEY를 설정합니다. DB는 127.0.0.1:5432, Redis는 127.0.0.1:6379와 설치 시 입력한 비밀번호를 사용합니다. 새 DB의 기본 FRONTEND_URL은 배포 중 이 값으로 설정됩니다. SSO·MCP의 기존 운영 URL은 대상 환경에 맞게 별도로 점검합니다.

Resend를 사용하지 않으면 server.env.production에 다음 값을 설정합니다.

dotenv
EMAIL_VERIFICATION_REQUIRED=false
RESEND_API=

이 설정은 이메일과 비밀번호 로그인을 유지하면서 신규 가입자의 이메일 확인 절차만 생략합니다. 비밀번호 찾기 메일은 별도 메일 발송 서비스가 필요하고 기존 비활성 계정은 자동으로 활성화되지 않습니다.

Windows에서 배포 ​

Windows OpenSSH 클라이언트, Git for Windows와 tar.exe가 필요합니다. 서버 호스트 키 지문을 별도 경로로 확인한 뒤 Windows PowerShell에서 실행합니다. .cmd 진입점은 해당 프로세스의 PowerShell 실행 정책만 우회하며, 회사 그룹 정책이 스크립트 서명을 강제하면 승인된 서명 절차가 필요합니다.

PM2 프로세스 이름은 server-intellidesk, agent-intellidesk, mcp-intellidesk입니다. 전체 배포는 기존 intellidesk-server, intellidesk-agent, intellidesk-mcp를 중지한 뒤 새 이름으로 시작합니다. 시작 명령이 실패하면 기존 프로세스를 복구하며, 성공하면 이전 이름을 제거하고 PM2 상태를 저장합니다.

powershell
cd C:\Work\intellidesk
$envDir = "$env:USERPROFILE\.config\intellidesk-secondary"
$key = "$env:USERPROFILE\.ssh\intellidesk-secondary"
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action Check -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key -EnvDir $envDir
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action All -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key -EnvDir $envDir

SSH 비밀번호를 사용할 때는 -KeyPath $key를 생략합니다. 배포는 커밋된 Git HEAD를 사용하므로 먼저 변경사항을 커밋합니다. 릴리스 아카이브에서 저장소의 환경파일과 SSO 개인키를 제외하고 대상 서버 전용 환경파일을 별도로 전달합니다. 앱은 http://10.20.30.40:8080에서, API는 http://10.20.30.40:8080/api/v1/auth/desktop-info에서 확인합니다.

사내 방화벽에는 SSH 22와 선택한 앱 포트만 필요한 클라이언트에 허용합니다. HTTP 로그인 정보는 암호화되지 않으므로 운영 정책에 따라 사내 TLS 프록시와 IP 인증서를 구성합니다. SSO를 사용한다면 별도 접속 포트와 인증서도 점검해야 합니다.

코드 난독화 ​

서버에 원본 소스를 두지 않으려면 -Obfuscate를 붙입니다. All과 Install에서 동작합니다. 서버로 보내기 전에 Windows에서 server, intellidesk-agent, mcp-server의 JavaScript를 난독화하고 테스트 파일을 제외합니다. 클라이언트는 빌드 결과만 서버에 두며, 이 옵션 없이도 원본 소스는 서버에 복사하지 않습니다.

powershell
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action All -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key -EnvDir $envDir -Obfuscate

난독화에는 저장소 루트의 npm install로 설치한 javascript-obfuscator와 Node.js, Git for Windows가 필요합니다. 난독화는 코드를 읽기 어렵게 만드는 수준이며, 서버 접근 권한자가 분석하는 것까지 막지는 못합니다. 비밀값은 환경파일에, 공용 패키지와 SQL 스키마는 원본대로 서버에 남습니다.

업데이트(패치) 배포 ​

첫 배포를 마친 서버에 새 코드를 반영할 때는 같은 -Action All을 다시 실행합니다. 서버 필수 구성은 다시 설치하지 않으므로 sudo 비밀번호가 필요하지 않습니다. 현재 체크아웃된 브랜치의 커밋된 HEAD를 전송하므로 배포할 브랜치와 커밋을 먼저 확인합니다.

powershell
git status
git log --oneline -1
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action All -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key -EnvDir $envDir

업데이트 배포는 코드 교체와 의존성 설치, DB 확인, 미적용 마이그레이션 실행, 클라이언트 빌드와 교체, 매뉴얼 빌드, PM2 재시작 순서로 진행합니다. 한 단계가 실패하면 이후 단계는 실행하지 않습니다. 매뉴얼 빌드 실패만 예외로 앱 배포를 계속합니다. PM2가 재시작하는 몇 초 동안 API 요청이 실패할 수 있습니다.

배포 전에 확인할 점

  • 배포 스크립트는 DB를 백업하지 않습니다. 중요한 마이그레이션이 포함되면 서버에서 sudo -u postgres pg_dump -Fc intellidesk > ~/intellidesk-$(date +%Y%m%d%H%M).dump로 먼저 백업합니다.
  • 배포할 때마다 Windows 환경파일로 서버의 .env.production을 덮어씁니다. 설정은 서버에서 직접 고치지 말고 Windows의 환경파일을 수정한 뒤 배포합니다.
  • 적용된 마이그레이션 파일은 체크섬으로 검증하므로 내용을 고치면 배포가 중단됩니다. 변경이 필요하면 YYYYMMDD_name.sql 형식의 새 파일을 추가합니다.

마이그레이션은 파일마다 별도 트랜잭션으로 적용합니다. 실패하면 해당 파일만 되돌려지고 앞서 성공한 파일은 적용된 상태로 남습니다. 새 코드는 이미 서버 폴더에 있지만 PM2는 이전 프로세스를 계속 실행하며, 프로세스가 재시작되면 새 코드로 시작합니다. 원인을 고친 커밋으로 다시 배포합니다. 자동 롤백은 없으므로 코드를 되돌리려면 이전 커밋을 체크아웃해 배포하고, DB는 백업에서 복원합니다.

배포 후 http://10.20.30.40:8080/api/v1/auth/desktop-info 응답과 서버의 pm2 ls에서 세 프로세스가 online인지 확인합니다. 화면이 바뀌지 않으면 브라우저에서 강력 새로고침(Ctrl+Shift+R)을 합니다.

맥·리눅스에서 배포 ​

맥이나 리눅스에서는 deploy/secondary-production/onprem-deploy.sh로 같은 절차를 진행합니다. 서버 IP, SSH 사용자, 배포 폴더, 환경파일 폴더를 대상 서버마다 설정 파일 하나에 적어 두고 이름으로 골라 실행합니다. 설정 항목은 저장소의 deploy/secondary-production/target.env.example을 참고합니다.

bash
mkdir -p ~/.config/intellidesk/targets ~/.config/intellidesk/env
cp deploy/secondary-production/target.env.example ~/.config/intellidesk/targets/customer-a.env
cp -R deploy/secondary-production/env-template ~/.config/intellidesk/env/customer-a

env-template은 운영 환경파일을 기본값으로 한 템플릿이며, 서버별 비밀값과 외부 서비스 키는 비어 있습니다. 복사한 폴더에서 [필수] 표시 항목을 채웁니다. ENCRYPTION_KEY, INTERNAL_API_KEY, SAP_MCP_CONNECTION_SECRET은 서버마다 새로 만들고 server와 mcp-server에 같은 값을 넣습니다. JWT_SECRET은 앱 서버에서만 보유하며 MCP에 복사하지 않습니다. 외부 MCP OAuth를 사용할 때는 MCP 연결 설정에 따라 공개키·발급자·대상 서비스를 지정합니다. 배포 명령은 시작 전에 필수 값이 비었거나 두 파일의 공유 값이 다르면 중단합니다.

SSH는 비밀번호 방식과 키 방식을 모두 지원합니다. 비밀번호 방식이면 설정 파일의 SSH_KEY를 비워 두며, 비밀번호는 명령을 실행할 때마다 한 번만 입력합니다. 처음 접속하는 서버는 화면에 나온 호스트 키 지문을 서버 관리자에게 받은 값과 비교한 뒤 승인합니다.

처음 배포할 때는 install을 실행합니다. 서버 필수 구성 설치, 빈 DB 초기화, 첫 배포를 이어서 진행하며, 서버 설치 단계에서 sudo 비밀번호를 한 번 더 묻습니다. PostgreSQL과 Redis 비밀번호는 server.env.production의 PGPASSWORD, REDIS_PASSWORD 값을 그대로 사용하므로 환경파일에 먼저 지정합니다. install은 서버마다 한 번만 실행합니다.

bash
bash deploy/secondary-production/onprem-deploy.sh install --target customer-a
bash deploy/secondary-production/onprem-deploy.sh admin --target customer-a

이후 추가 배포는 deploy를 실행합니다. 커밋된 Git HEAD를 전송하고 의존성 설치, 마이그레이션, 클라이언트 빌드, PM2 재시작을 진행합니다. 커밋하지 않은 변경이 있으면 목록을 보여 주고 배포에서 제외합니다.

bash
bash deploy/secondary-production/onprem-deploy.sh check --target customer-a
bash deploy/secondary-production/onprem-deploy.sh deploy --target customer-a

기존 계정의 비밀번호를 재설정할 때는 admin에 --reset을 붙입니다.

이메일 인증과 슈퍼 관리자 ​

첫 배포 후 Windows PowerShell에서 이메일 인증 설정을 적용하고 슈퍼 관리자 계정을 생성합니다.

powershell
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action EmailVerification -Mode Disable -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key -EnvDir $envDir
.\deploy\secondary-production\Deploy-SecondaryProduction.cmd `
  -Action SuperAdmin -ServerIp 10.20.30.40 -SshUser ubuntu -KeyPath $key

슈퍼 관리자 명령은 테넌트 ID, 이메일, 사용자 ID, 이름과 초기 비밀번호를 대화형으로 받습니다. 새 DB의 테넌트 ID는 internal입니다. 계정은 활성·이메일 인증 완료 상태와 SUPER_ADMIN·ADMIN 권한으로 생성되고 첫 로그인 후 비밀번호 변경이 강제됩니다. 기존 계정을 복구할 때만 -ResetExisting을 추가합니다. 이메일 인증을 다시 켜려면 Resend 값을 설정한 뒤 -Mode Enable을 실행합니다.

독립 SSO 운영 ​

IntelliConnect는 이 배포에 포함되지 않습니다. 별도 intelli-sso 저장소에서 배포하며, 기존 서비스의 DB·인증서·환경 파일을 유지합니다. 앱과 MCP의 SSO URL을 독립 서비스 주소로 지정하고 MCP의 OAUTH_PUBLIC_KEY_PATH를 배포한 인증서 경로로 설정합니다. 기존 SSO가 실행 중인 서버에서는 IntelliDesk 배포가 해당 프로세스를 중지하지 않습니다.

기본 운영 경로는 /home/ubuntu/apps/intelliconnect입니다. 서버의 .env.production에는 SSO_LOG_DIR=/home/ubuntu/apps/intelliconnect/service/logs를, MCP의 .env.production에는 OAUTH_PUBLIC_KEY_PATH=/home/ubuntu/apps/intelliconnect/service/certs/idp-certificate.pem을 설정합니다. 다른 경로에 배포하면 두 값을 해당 위치로 바꿉니다. 인증서 검증과 SSO 로그 조회가 새 경로에서 동작하고 기존 폴더를 사용하는 프로세스가 없음을 확인한 뒤 IntelliDesk 내부의 intelli-sso와 sap-sso 폴더를 백업 위치로 옮깁니다.

SAP 공용 패키지 ​

SAP 연결과 ABAP 공통 처리는 별도 intelli-packages 저장소에서 관리합니다. IntelliDesk에는 버전이 고정된 두 패키지 배포물이 포함되며 배포 스크립트가 이를 먼저 전송합니다. 운영 서버에 원본 저장소를 설치할 필요는 없습니다. abap-analysis는 기존 공용 패키지 경로를 사용합니다.

Intellidesk