환경 변수 레퍼런스
스튜디오 서버가 읽는 환경 변수 전체입니다. 화면(환경설정)에서 바꾸는 값과 달리, 여기 값들은 파일을 고치고 재기동해야 반영됩니다.
정본은 /etc/kopens/plantpulse-studio.env
/etc/kopens/plantpulse-studio.env
.env 는 더 이상 읽지 않습니다옛 경로(설치 디렉터리의 .env)에 값을 넣어도 반영되지 않습니다. 옛 파일이 남아
있으면 스크립트가 그 사실을 알려 줍니다. 값을 고칠 때는 위 정본 경로를 쓰세요.
권한은 chmod 600 으로 두세요 — API 키가 들어 있는 파일입니다.
이미지와 버전
| 변수 | 기본값 | 설명 |
|---|---|---|
REGISTRY | docker.kopens.io/ps | 이미지를 받아올 레지스트리. 비우면 로컬 태그만 씁니다(직접 빌드한 경우) |
PP_IMAGE_TAG | (빈 값) | 우리 이미지 셋(server · web)의 칼버 태그 |
PS_IMAGE_TAG_SERVER | (없음) | plantpulse-studio-server 만 다른 태그로 띄울 때 |
PS_IMAGE_TAG_WEB | (없음) | plantpulse-studio-web 만 다른 태그로 띄울 때 |
PS_IMAGE_TAG_AGENT_SERVER | 0c5ac7fb | 에이전트 사이드카. 칼버가 아니라 다이제스트 핀(OpenHands SDK v1.43.1)이라 PP_IMAGE_TAG 를 따라가지 않습니다 |
PP_IMAGE_TAG 는 비워 두는 것이 권장입니다비워 두면 bin/start.sh 가 VERSION 파일의 칼버를 읽어 릴리즈마다 자동으로 따라갑니다.
여기에 달을 손으로 적으면 그 값이 그대로 굳습니다 — 실제로 그래서 한 달 전 이미지가
뜬 적이 있습니다.
한 시점에 못 박아야 한다면 달(2026.09)이 아니라 스냅샷 태그(2026.09-20260911)를
넣으십시오. date +%Y.%m 로 계산하지 마십시오 — 매달 1일 00:00~04:00 KST 사이에는
아직 존재하지 않는 태그를 가리킵니다(그 달 릴리즈가 04:00 에 돕니다).
TAG · AGENT_SERVER_TAG 라는 변수는 없습니다compose 가 읽는 것은 위 표의 이름들뿐입니다. TAG=2026.08 처럼 적어 두면
아무 일도 일어나지 않고 스택은 VERSION 의 칼버로 뜹니다 — 못 박았다고 생각한 채
따라가고 있는 상태가 됩니다.
특정 릴리즈 시점에 고정하려면 스냅샷 태그를 쓰세요 — 예: TAG=2026.08-20260810.
:::
로케일과 시간대
플랫폼·Edge 와 같은 변수 이름을 씁니다.
| 변수 | 기본값 | 설명 |
|---|---|---|
PP_LANG | en | 웹 기본 언어(ko / en). 브라우저에 저장된 값이 우선합니다 |
PP_TZ | Asia/Seoul | IANA 시간대 ID. "오늘 / 어제" 같은 상대 시간 해석 기준 |
한국어 현장이면 PP_LANG=ko 로 두세요.
데이터 저장 위치
| 변수 | 기본값 | 설명 |
|---|---|---|
DATA_ROOT | /var/lib/pp-studio | 워크스페이스 · 빌드 산출물 · 상태가 전부 이 아래 저장됩니다 |
백업 대상이 이 경로입니다 → 백업과 복구.
데이터베이스 — 외부 PostgreSQL
스튜디오는 외부 PostgreSQL 을 씁니다. 플랫폼이 쓰는 것과 같은 PG 를 나눠 쓰면 됩니다.
| 변수 | 예 |
|---|---|
DATABASE_URL | postgres://<user>:<password>@<db-host>:5432/ppstudio |
🔴 PG_PASSWORD 라는 변수는 없습니다. DB 비밀번호는 DATABASE_URL 한 줄 안에
들어갑니다 — 비밀번호만 따로 바꾸는 변수를 두면 URL 과 어긋날 수 있어서 한 줄로 모았습니다.
DATABASE_URL 은 필수입니다비어 있으면 설치가 그 자리에서 멈추고 무엇이 비었는지 알려 줍니다 — 그럴듯한 기본값을 지어내지 않습니다.
서버는 있는 데이터베이스에 마이그레이션만 합니다. DB 와 역할을 만들지는 않습니다 —
bin/provision-platform-db.sh 가 그 일을 합니다.
설치 의 「데이터베이스 준비」를 보십시오.
플랫폼 연동
| 변수 | 설명 |
|---|---|
PP_API_URL | 실데이터 조회와 로그인 인증을 위임하는 플랫폼 주소 |
PP_API_TOKEN | 그 플랫폼의 api_key |
로그나 컨테이너 안에서는 PLATFORM_API_TARGET · PLATFORM_API_KEY 로 보입니다.
.env 에 적는 이름은 PP_API_URL · PP_API_TOKEN 입니다 — 아래 「두 층의 이름」을
보십시오.
리스너 포트
| 변수 | 기본값 | 설명 |
|---|---|---|
PORT | 5170 | 스튜디오 서버(오케스트레이터)의 API 포트. 웹이 내부에서 프록시하므로 밖에 열 필요는 없습니다 — 진단용(curl localhost:5170/health) |
APPS_PORT | 5171 | 프리뷰와 배포된 앱을 서빙하는 별도 리스너 포트 |
- 포트로 직접 접속하는 설치 — 방화벽에서 이 포트도 열어야 프리뷰·배포앱·QR 접속이 됩니다.
- 리버스 프록시 뒤 — 열지 않아도 됩니다. 프록시가 같은 도메인의
/container/preview·/apps를 이 리스너로 넘깁니다 → 도메인과 리버스 프록시.
클라이언트가 상대 경로만 씁니다. 프리뷰·배포앱의 공개 URL 을 따로 알려 줄 필요가 없어 80/443 만 여는 구성에서도 그대로 동작합니다.
AI 프로바이더
여기 값은 초기값입니다. 화면(환경설정 → AI)에서 넣은 값이 이 값을 덮습니다.
| 변수 | 기본값 | 설명 |
|---|---|---|
AI_PROVIDER | openai-compatible | 비우면 언제나 openai-compatible 입니다 |
PI_LLM_URL | (빈 값 — 필수) | 게이트웨이 주소. 기본값을 두지 않습니다 |
AI_MODEL | gpt-4o | 모델명 |
PI_LLM_API_KEY | (빈 값 — 필수) | OpenAI 호환 키 |
PS_ANTHROPIC_API_KEY | (빈 값) | 클라우드 Claude 를 쓸 때만 |
⚠ PI_LLM_URL 과 PI_LLM_API_KEY 는 비어 있으면 스택이 기동을 거부합니다.
PI_LLM_URL 에 그럴듯한 기본값을 넣지 않는 이유게이트웨이가 그 호스트에 없으면 채팅이 통째로 fetch failed 가 되는데, 값이 그럴듯해
보여 원인 찾기가 비쌉니다. 실제 주소를 적으세요. 넣은 값이 맞는지는 환경설정 → AI 탭의
연결 테스트로 저장 전에 확인할 수 있습니다 → 환경설정(관리자).
프로바이더는 AI_PROVIDER 로 명시합니다. 어떤 키가 들어 있느냐로 고르면 env 구성에
따라 무엇으로 뜰지 예측할 수 없습니다.
CORS
| 변수 | 기본값 | 설명 |
|---|---|---|
STUDIO_CORS_ORIGINS | (빈 값 = same-origin) | 별도 도메인에서 접근할 때만 지정 |
설치·기동 플래그
.env 가 아니라 명령 앞에 붙여 쓰는 것들입니다(SKIP_DOCKER=1 bash bin/install.sh).
| 변수 | 기본값 | 설명 |
|---|---|---|
SKIP_DOCKER | 0 | 1 이면 Docker 설치 단계를 건너뜁니다(이미 깔려 있을 때) |
SKIP_WAIT | 0 | 1 이면 기동 완료를 기다리지 않고 스크립트가 끝납니다 |
WAIT_READY_MIN | 10 | 기동 완료를 기다리는 시간(분). 느린 회선·큰 이미지에서 늘립니다 |
에이전트 사이드카 자원
| 변수 | 기본값 | 설명 |
|---|---|---|
AGENT_SERVER_CPUS | 1 | 빌더 사이드카에 주는 CPU 수 |
AGENT_SERVER_MEMORY | 2g | 빌더 사이드카 메모리 한계 |
env 로 나르지 않는 것
사용자 계정과 역할은 환경 변수로 정하지 않습니다. 서버가 계정이 하나도 없을 때
관리자 하나를 DB 에 심고, 그 뒤로는 앱의 사용자 관리 화면에서 추가·삭제하고
역할(admin / builder / viewer)도 거기서 줍니다.
관련 문서
- 설치 — 처음 값을 채우는 절차
- 비밀 관리 — 키를 어디에 두는가
- 환경설정(관리자) — 화면에서 바꾸는 값
- 도메인과 리버스 프록시
두 층의 이름 — .env 와 컨테이너 안이 다릅니다
🔴 여기서 실수가 가장 많이 납니다. 로그·docker inspect·제품 소스에서 보는 이름과
.env 에 적는 이름이 다릅니다. 적는 것은 왼쪽입니다.
.env 에 적는 이름 | 컨테이너 안에서 보이는 이름 |
|---|---|
PP_API_URL | PLATFORM_API_TARGET |
PP_API_TOKEN | PLATFORM_API_KEY |
PI_LLM_URL | AI_BASE_URL |
PI_LLM_API_KEY | AI_API_KEY |
PS_ANTHROPIC_API_KEY | ANTHROPIC_API_KEY |
나머지(DATABASE_URL · DATA_ROOT · APPS_PORT · AI_PROVIDER · AI_MODEL ·
STUDIO_CORS_ORIGINS)는 양쪽 이름이 같습니다.
한 서버에 여러 제품(플랫폼 · AI · 스튜디오)이 함께 놓입니다. .env 쪽 이름에 제품
접두어(PP_ 플랫폼 · PI_ 공용 인프라 · PS_ 스튜디오)를 붙여 두면 어느 제품 값인지가
이름만 보고 드러나고, 값 하나를 두 제품이 나눠 쓸 때도 헷갈리지 않습니다.