본문으로 건너뛰기

설치

PlantPulse Studio 를 고객사 서버 한 대에 설치하는 절차입니다. 도커 컨테이너 4종(웹 · 서버 · 빌더 사이드카 · PostgreSQL)으로 구성되며, 설치 스크립트가 도커 설치부터 기동까지 자동으로 처리합니다.

인터넷이 되지 않는 폐쇄망이라면 이 문서 대신 에어갭 설치를 보세요.


1. 사전 요구사항

서버 사양

항목최소권장비고
CPU4 코어8 코어 이상앱 세션마다 빌드가 돌아갑니다
메모리8 GB16 GB 이상아래 표 참조
디스크50 GB 여유100 GB 이상컨테이너 이미지만 약 6 GB
OSLinux (x86_64)RHEL 9 / Rocky 9 / Ubuntu 22.04 이상systemd + 도커가 돌면 됩니다

메모리 산정 근거 — 스택이 고정으로 잡는 상한값입니다.

컨테이너메모리 상한
studio-server (오케스트레이터)2 GB
agent-server (빌더 사이드카)2 GB
studio-web (nginx)256 MB
postgres (번들 모드)제한 없음(실사용 수백 MB)
앱 세션 컨테이너 1개당2 GB

앱 세션 컨테이너는 사용자가 프로젝트를 열 때마다 하나씩 뜨고, 30분간 쓰지 않으면 자동 회수됩니다. 동시 작업자 수만큼 2 GB 를 더해 잡으세요.

동시 사용자 3~5명이 목표라면

16 GB 메모리 · 8 코어 · 100 GB 디스크를 기준으로 잡으면 여유롭습니다.

소프트웨어

  • Docker Engine + Docker Compose v2 (v2.22 이상) 설치되어 있지 않으면 원라인 설치 스크립트가 자동으로 설치합니다.
  • curl, tar (대부분의 배포판에 기본 포함)

포트와 방화벽

스택은 host 네트워크로 동작합니다. 즉 컨테이너 포트가 호스트에 그대로 열리므로, 접근 통제는 오직 서버 방화벽으로만 이뤄집니다.

포트용도방화벽
80스튜디오 UI (nginx)개방
5171앱 리스너 — 프리뷰 · 배포앱 · QR 접속개방(필수)
5170스튜디오 API웹이 내부 프록시 — 개방 불필요(진단용)
5432PostgreSQL(번들 모드)127.0.0.1 로만 바인드 — 개방 금지
8000빌더 사이드카(agent-server)루프백 전용 — 절대 개방 금지
5172MCP 도구 브리지루프백 전용 — 절대 개방 금지
5171 을 막으면 프리뷰와 배포앱이 안 열립니다

프리뷰(/preview/…)와 배포앱(/apps/…)은 보안 경계 때문에 스튜디오와 다른 오리진 (기본 5171 포트)에서 서빙됩니다. 채팅으로 만든 앱의 자바스크립트가 스튜디오 로그인 토큰에 접근하지 못하게 하는 장치입니다. 5171 을 열지 않으면 화면이 비어 보입니다.

8000 · 5172 는 인증이 없습니다

두 포트는 내부 부품 간 통신 전용이며 인증 절차가 없습니다. 외부에 노출되면 전체 사용자 워크스페이스를 읽고 쓸 수 있게 됩니다. 스택은 기본적으로 루프백에만 바인드하지만, 방화벽에서도 절대 열지 마세요.

레지스트리 접근

이미지는 KOPENS 레지스트리(docker.kopens.io)에서 받습니다. 설치 전에 한 번 로그인하세요. 계정은 KOPENS 운영팀이 발급합니다.

docker login docker.kopens.io

2. 데이터베이스 선택

설치 전에 둘 중 하나를 정하세요. 나중에 바꿀 수도 있지만 데이터 이관이 필요합니다.

=== "(A) 번들 PostgreSQL — 기본"

스택이 PostgreSQL 컨테이너를 함께 띄웁니다. 별도 DB 서버가 없는 현장의 기본값입니다.

COMPOSE_PROFILES=bundled-pg
PG_DB=ppstudio
PG_USER=ppstudio
PG_PASSWORD=`<충분히 긴 임의 문자열>`

데이터는 DATA_ROOT/postgres 아래에 저장됩니다.

=== "(B) 외부·공용 PostgreSQL"

플랫폼용 PostgreSQL 이 이미 있는 현장이라면 이중 인프라를 없앨 수 있습니다. COMPOSE_PROFILES 줄을 지우고 접속 URL 만 지정하면 PostgreSQL 컨테이너가 아예 뜨지 않습니다.

# COMPOSE_PROFILES 줄 삭제
DATABASE_URL=postgres://`<사용자>`:`<비밀번호>`@`<DB호스트>`:5432/`<DB명>`

빈 데이터베이스만 준비하면 됩니다 — 테이블은 서버가 처음 뜰 때 자동으로 만듭니다.

PG 비밀번호는 처음에 정한 값을 유지하세요

번들 모드에서 데이터가 이미 쌓인 뒤 PG_PASSWORD 만 바꾸면, 기존 데이터 디렉터리의 계정과 어긋나 스택이 뜨지 않습니다. 비밀번호를 바꾸려면 PostgreSQL 안에서 계정 비밀번호를 먼저 변경해야 합니다.


3. 설치 (원라인 · 권장)

서버에 root 로 접속해 한 줄을 실행합니다. 스크립트가 도커 확인·설치 → 패키지 내려받기 → .env 생성 → 스택 기동까지 수행합니다.

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo bash

설치 위치는 /opt/kopens/plantpulse-studio-docker 이고, 이후 모든 운영 명령은 이 디렉터리에서 실행합니다.

값을 미리 정해 무인 설치

환경변수는 bash 앞에 붙여야 파이프를 타고 전달됩니다.

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh \
| sudo PLATFORM_API_TARGET=https://192.168.0.41 \
DATA_ROOT=/data1/pp-studio \
ANTHROPIC_API_KEY=sk-ant-... \
bash

값을 물어보게 하기

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo INTERACTIVE=1 bash

빈 항목마다 프롬프트가 뜹니다(데이터 루트 · PG 비밀번호 · 플랫폼 주소 · 관리자 계정 등).

다시 실행해도 안전합니다

같은 서버에서 설치 스크립트를 재실행하면 코드만 갱신되고 .env 와 로컬 백업(dist/)은 보존됩니다. 업그레이드 용도로 그대로 써도 됩니다.

설치 스크립트가 404 나 옛 버전을 준다면

CDN 캐시가 남아 있을 수 있습니다. URL 뒤에 ?v=$(date +%s) 를 붙여 다시 받으세요.


4. 설치 (수동)

패키지를 이미 받아 놓았거나 .env 를 직접 작성하려는 경우입니다.

cd /opt/kopens/plantpulse-studio-docker
sudo cp .env.example /etc/kopens/plantpulse-studio.env
sudo vi /etc/kopens/plantpulse-studio.env # 아래 표를 보고 값 채우기
sudo chmod 600 /etc/kopens/plantpulse-studio.env
bash bin/start.sh
설정 정본은 /etc/kopens/plantpulse-studio.env 하나다

환경변수 파일은 설치 디렉터리 안이 아니라 repo 트리 밖/etc/kopens/plantpulse-studio.env 에 둡니다. 권한은 0600 입니다. platform · ai · studio 세 제품이 같은 규약으로 /etc/kopens/plantpulse-<제품>.env 를 씁니다.

설치 디렉터리 루트의 .env옛 경로입니다. compose 도 나머지 스크립트도 이제 그 파일을 읽지 않으므로, 거기를 고쳐도 스택은 바뀌지 않습니다. 기존 설치의 .envbin/install.sh 가 새 경로로 옮겨 줍니다(새로 만들지 않습니다 — 새로 만들면 DB 는 옛 비밀번호인데 env 는 새 기본값이 되어 다음 재기동에서 죽습니다).

환경변수 주요 항목

항목설명기본값
REGISTRY이미지 레지스트리. 비우면 pull 없이 로컬 이미지만 사용(에어갭)docker.kopens.io/ps
TAG이미지 태그. 특정 버전 고정 시 2026.08 처럼 지정latest
DATA_ROOT모든 데이터(워크스페이스 · 빌드 · 상태 · DB)가 저장될 경로/var/lib/pp-studio
PLATFORM_API_TARGET실데이터·인증을 위임할 PlantPulse 플랫폼 주소https://192.168.0.41
APPS_PORT앱 리스너 포트(프리뷰·배포앱)5171
PP_LANG웹 기본 언어 ko / enen
PP_TZ타임존(IANA ID). "오늘 · 어제 · 지난주" 해석 기준Asia/Seoul
STUDIO_CORS_ORIGINS다른 도메인에서 API 를 부를 때만 지정. 기본은 차단비움
COMPOSE_PROFILES / DATABASE_URL데이터베이스 선택 — 위 2절 참조bundled-pg
ANTHROPIC_API_KEYAI · 플랫폼 키 — 비밀 관리 참조비움
계정과 역할은 환경변수로 나르지 않습니다

STUDIO_LOCAL_USERS · STUDIO_ADMINS · STUDIO_VIEWERS없어졌습니다(2026-08-18). 서버가 계정이 하나도 없을 때 부트스트랩 관리자를 DB 에 심고, 그 뒤로는 앱의 환경설정 → 사용자 관리에서 계정을 추가·삭제하고 역할(관리자 / 빌더 / 뷰어)을 줍니다. 아래 7. 첫 로그인 참조.

한국어 현장은 PP_LANG=ko 를 직접 넣으세요

원라인 설치가 만드는 .env 에는 PP_LANG · PP_TZ 줄이 없어 기본값(en / Asia/Seoul)이 적용됩니다. 한국어로 띄우려면 .envPP_LANG=ko 를 추가하고 bash bin/restart.sh.

.env 를 고친 뒤에는 반드시 bin/restart.sh

docker restart.env 를 다시 읽지 않습니다. 값이 반영되지 않은 채로 "왜 안 바뀌지"를 한참 찾게 되는 대표적인 함정입니다. 자세한 내용은 비밀 관리에 있습니다.


5. 스택 구성 확인

설치가 끝나면 컨테이너 4종이 떠 있어야 합니다.

컨테이너역할
pp-studio-web스튜디오 UI(nginx :80) — 정적 화면 + API 프록시
pp-studio-server오케스트레이터(:5170) — 에이전트 · 세션 · 배포 · 앱 리스너(:5171)
pp-studio-agent-server빌더 사이드카 — 앱 코드를 작성하는 코딩 엔진
pp-studio-postgres번들 PostgreSQL (외부 DB 를 쓰면 뜨지 않습니다)

여기에 더해, 사용자가 프로젝트를 열면 앱 세션 컨테이너가 프로젝트마다 하나씩 뜹니다. 스택 컨테이너가 아니라 서버가 필요할 때 만들고 유휴 30분 후 회수합니다.


6. 기동 확인

cd /opt/kopens/plantpulse-studio-docker

bash bin/status.sh # 컨테이너 상태 + 헬스 + 세션 컨테이너 수
curl -s localhost:5170/health

설치 직후에는 종합 점검 스크립트를 한 번 돌리는 것을 권장합니다. 헬스 · 웹 응답 · 실제 로그인 · 세션 런타임 이미지 · 컨테이너 상태를 모두 검사하고, 하나라도 실패하면 오류로 끝납니다.

bash bin/smoke-install.sh
✓ health
✓ client-config → {"lang":"ko",...}
✓ web 200
✓ 로그인(부트스트랩 계정)
✓ 세션 런타임 이미지
✓ 컨테이너 running(...)
✅ 설치 스모크 통과
세션 런타임 이미지

앱 세션 컨테이너는 plantpulse-studio-runtime 이미지를 씁니다. bin/start.sh 가 자동으로 내려받아 태그하지만, 실패하면 ⚠️ 세션 런타임 이미지 없음 경고가 뜨고 프로젝트 열기가 실패합니다. 이때는 레지스트리 로그인 상태를 확인하고 bash bin/start.sh 를 다시 실행하세요.


7. 첫 로그인

브라우저에서 http://<서버IP>/ 로 접속합니다.

계정이 하나도 없는 상태에서 서버가 처음 뜨면 부트스트랩 관리자를 DB 에 심습니다.

항목
아이디admin
비밀번호admin123!

부팅 로그에도 남습니다 — 부트스트랩 관리자 생성: admin — 로그인 후 비밀번호를 바꿀 것.

가장 먼저 이 비밀번호를 바꾸세요

모든 설치에서 같은 값입니다. 로그인하자마자 환경설정 → 사용자 관리에서 바꾸세요 (비밀번호 재설정, 6자 이상). 환경변수 파일을 고치는 것으로는 바뀌지 않습니다 — 서버는 로그인할 때 ①DB → ②환경변수 순으로 보고 DB 에서 잡히면 거기서 끝냅니다.

로그인 후 할 일:

  1. 환경설정 → 사용자 관리 — 부트스트랩 관리자 비밀번호 변경, 현장 사용자 계정 생성, 역할(관리자 / 빌더 / 뷰어) 지정
  2. 비밀번호 · API 키 변경 — DB 계정과 AI 키를 bin/passwd.sh 로 한 번에 회전. 커미셔닝 때 한 번만 하면 됩니다
  3. 환경설정 → AI — AI 프로바이더와 키 연결 상태 확인
  4. 환경설정 → 플랫폼 — 플랫폼 주소·키 연결 확인(실데이터 조회에 필요)

자세한 화면 설명은 시작하기환경설정(관리자)에 있습니다.

8. 일상 운영 명령

모든 명령은 설치 디렉터리(/opt/kopens/plantpulse-studio-docker)에서 실행합니다.

bash bin/start.sh # 시작(레지스트리에서 최신 이미지 pull 포함)
bash bin/stop.sh # 중지 — 데이터는 그대로 보존, 세션 컨테이너도 정리
bash bin/restart.sh # 재기동(.env 변경 반영)
bash bin/status.sh # 상태 요약
bash bin/logs.sh # 서버 로그 팔로우(기본 studio-server)
bash bin/logs.sh studio-web # 특정 서비스 로그

세션 컨테이너만 따로 보려면,

docker ps --filter label=plantpulse-studio=1

9. 업데이트

bin/start.sh 는 레지스트리에서 이미지를 다시 받아 갱신합니다. 설치 스크립트를 다시 실행하면 운영 스크립트까지 함께 갱신됩니다(.env · 백업은 보존).

=== "이미지만 갱신"

cd /opt/kopens/plantpulse-studio-docker
bash bin/start.sh

=== "패키지까지 갱신"

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo bash

버전 고정

버전 표기는 YYYY.MM 형식입니다(예: 2026.08). 자동 갱신을 원치 않는 운영 환경에서는 .env 에 태그를 고정하세요.

TAG=2026.08
업데이트 전에는 백업

bash bin/backup.sh 를 먼저 돌려 두세요. 절차는 백업과 복구에 있습니다.

이미지 서명 검증(선택)

배포된 이미지가 KOPENS 가 서명한 것인지 확인할 수 있습니다. cosign 이 설치돼 있어야 합니다.

cd /opt/kopens/plantpulse-studio-docker
bash bin/verify-images.sh
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-server:2026.08
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-web:2026.08
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-runtime:2026.08

다음 단계