snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,262 @@
---
title: Docker Compose
icon: docker
---
<Warning>
Docker 컨테이너는 프로덕션 호스팅 또는 셀프 호스팅용입니다. 기여하려면 [로컬 설정](/l/ko/developers/contribute/capabilities/local-setup)을 확인하세요.
</Warning>
## 개요
이 가이드는 Docker Compose를 사용하여 Twenty 애플리케이션을 설치 및 구성하기 위한 단계별 지침을 제공합니다. 프로세스를 간단하게 만들고 설정을 망칠 수 있는 일반적인 함정을 피하는 것이 목적입니다.
**중요:** 이 가이드에서 명시적으로 언급된 설정만 수정하세요. 다른 구성을 변경하면 문제가 발생할 수 있습니다.
고급 설정을 위해 [환경 변수 설정](/l/ko/developers/self-host/capabilities/setup) 문서를 참조하세요. 모든 환경 변수는 변수에 따라 서버 및/또는 작업자 수준에서 `docker-compose.yml` 파일에 선언되어야 합니다.
## 시스템 요구 사항
* RAM: 환경에 최소 2GB의 RAM이 있는지 확인하십시오. 메모리가 충분하지 않으면 프로세스가 중단될 수 있습니다.
* Docker 및 Docker Compose: 둘 다 설치되고 최신 상태인지 확인하세요.
## 옵션 1: 한 줄 스크립트
단일 명령으로 최신 안정 버전의 Twenty를 설치하십시오:
```bash
bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh)
```
특정 버전 또는 브랜치를 설치하려면:
```bash
VERSION=vx.y.z BRANCH=branch-name bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh)
```
* 원하는 버전 번호로 x.y.z를 대체하십시오.
* 설치할 브랜치 이름으로 branch-name을 대체하십시오.
## 옵션 2: 수동 단계
수동 설정을 위해 다음 단계를 따릅니다.
### 단계 1: 환경 파일 설정
1. **.env 파일 생성**
예제 환경 파일을 워킹 디렉토리의 새 .env 파일로 복사합니다.
```bash
curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example
```
2. **암호화 키 생성하기**
고유한 랜덤 문자열을 생성하기 위해 다음 명령을 실행하세요:
```bash
openssl rand -base64 32
```
**중요:** 이 값을 비공개로 유지/공유하지 마십시오. `ENCRYPTION_KEY`를 잃어버리면 데이터베이스에 저장된 모든 비밀(예: OAuth 토큰, 애플리케이션 변수, TOTP 비밀 등)에 대한 액세스를 잃게 됩니다.
3. **`.env` 업데이트**
생성된 토큰으로 .env 파일의 플레이스홀더 값을 대체합니다.
```ini
ENCRYPTION_KEY=random_string
```
중단 없이 키를 회전하는 방법은 [키 회전 가이드](/l/ko/developers/self-host/capabilities/key-rotation)를 참조하세요.
4. **Postgres 비밀번호 설정**
.env 파일에서 특수 문자가 없는 강력한 비밀번호로 `PG_DATABASE_PASSWORD` 값을 업데이트하십시오.
```ini
PG_DATABASE_PASSWORD=my_strong_password
```
### 단계 2: Docker Compose 파일 얻기
작업 디렉토리에 `docker-compose.yml` 파일을 다운로드합니다.
```bash
curl -o docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/docker-compose.yml
```
### 단계 3: 애플리케이션 시작
Docker 컨테이너 시작:
```bash
docker compose up -d
```
### 단계 4: 애플리케이션에 액세스
twentyCRM을 개인 컴퓨터에 호스팅하는 경우 브라우저를 열고 [http://localhost:3000](http://localhost:3000)으로 이동하세요.
서버에서 호스팅하는 경우 서버가 실행 중이며 모든 것이 문제없는지 확인하십시오.
```bash
curl http://localhost:3000
```
## 구성
### Twenty를 외부 액세스에 노출
기본적으로 Twenty는 `localhost`의 포트 `3000`에서 실행됩니다. UI는 브라우저 자체의 origin에서 API를 확인하므로, 컨테이너에 도달할 수 있는 어떤 호스트명에서도 로드됩니다. 하지만 여전히 `SERVER_URL`은 공개용 URL로 설정해야 합니다. 서버는 이를 생성된 링크(이메일, OAuth 콜백)와 HTTPS 감지(보안 쿠키용)에 사용합니다.
#### `SERVER_URL` 이해하기
* **프로토콜:** 구성에 따라 `http` 또는 `https`를 사용하십시오.
* SSL을 설정하지 않은 경우 `http`를 사용합니다.
* SSL이 구성되어 있으면 `https`를 사용하십시오.
* **도메인/IP:** 애플리케이션을 액세스할 수 있는 도메인 이름 또는 IP 주소입니다.
* **포트:** 기본 포트(`http`의 경우 `80`, `https`의 경우 `443`)를 사용하지 않는 경우 포트 번호를 포함하십시오.
### SSL 요구 사항
SSL(HTTPS)는 일부 브라우저 기능이 제대로 작동하기 위해 필수입니다. 이러한 기능은 로컬 개발 중에는 작동할 수 있지만 (브라우저는 localhost를 다르게 처리합니다), 일반 도메인에 Twenty를 호스팅할 때는 적절한 SSL 설정이 필요합니다.
예를 들어, 클립보드 API는 안전한 컨텍스트가 필요할 수 있습니다. 응용 프로그램 내 복사 버튼과 같은 일부 기능은 HTTPS가 활성화되지 않으면 작동하지 않을 수 있습니다.
최적의 보안 및 기능을 위해 SSL 종료와 함께 Reverse Proxy 뒤에 Twenty를 설정하는 것을 강력히 권장합니다.
#### `SERVER_URL` 설정
1. **접속 URL 결정**
* **리버스 프록시 없이(직접 접속):**
리버스 프록시 없이 애플리케이션에 직접 액세스:
```ini
SERVER_URL=http://your-domain-or-ip:3000
```
* **리버스 프록시 사용 (표준 포트):**
SSL이 구성된 Nginx 또는 Traefik과 같은 리버스 프록시를 사용하는 경우:
```ini
SERVER_URL=https://your-domain-or-ip
```
* **리버스 프록시 사용 (사용자 지정 포트):**
비표준 포트를 사용하는 경우:
```ini
SERVER_URL=https://your-domain-or-ip:custom-port
```
2. **`.env` 파일 업데이트**
`.env` 파일을 열고 `SERVER_URL`을 업데이트하십시오:
```ini
SERVER_URL=http(s)://your-domain-or-ip:your-port
```
**예시:**
* SSL 없이 직접 접근:
```ini
SERVER_URL=http://123.45.67.89:3000
```
* SSL을 사용한 도메인 접근:
```ini
SERVER_URL=https://mytwentyapp.com
```
3. **애플리케이션 재시작**
변경 사항을 적용하기 위해 Docker 컨테이너를 재시작하십시오.
```bash
docker compose down
docker compose up -d
```
#### 고려 사항
* **리버스 프록시 구성:**
리버스 프록시가 올바른 내부 포트(`3000` 기본값)로 요청을 전달하도록 확인하십시오. SSL 종료와 필요한 헤더를 구성하십시오.
* **방화벽 설정:**
외부 액세스를 허용하기 위해 방화벽에서 필요한 포트를 엽니다.
* **일관성:**
`SERVER_URL`은 사용자가 브라우저에서 애플리케이션에 액세스하는 방식과 일치해야 합니다.
#### 영속성
* **데이터 볼륨:**
Docker Compose 구성은 데이터베이스 및 서버 저장소의 데이터를 영구적으로 저장하기 위해 볼륨을 사용합니다.
* **무상태 환경:**
무상태 환경(예: 특정 클라우드 서비스)에 배포하는 경우 데이터 지속성을 위해 외부 저장소를 구성합니다.
## 백업 및 복원
정기 백업은 CRM 데이터를 손실로부터 보호합니다.
### 데이터베이스 백업 생성
```bash
docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql
```
### 일일 백업 자동화
crontab에 추가하세요 (`crontab -e`):
```bash
0 2 * * * docker exec twenty-postgres pg_dump -U postgres twenty > /backups/twenty_$(date +\%Y\%m\%d).sql
```
### 백업에서 복원
1. 애플리케이션을 중지하세요:
```bash
docker compose stop server worker
```
2. 데이터베이스를 복원하세요:
```bash
docker exec -i twenty-postgres psql -U postgres twenty < backup_20240115.sql
```
3. 서비스 재시작:
```bash
docker compose up -d
```
### 백업 모범 사례
* **복원을 정기적으로 테스트하세요** — 백업이 실제로 작동하는지 확인하세요
* **백업을 오프사이트에 보관하세요** — 클라우드 스토리지(S3, GCS 등)를 사용하세요
* **민감한 데이터를 암호화하세요** — 암호화를 통해 백업을 보호하세요
* **여러 사본을 유지하세요** — 일간, 주간, 월간 백업을 보관하세요
## 문제 해결
문제가 발생하면 [문제 해결](/l/ko/developers/self-host/capabilities/troubleshooting)에서 해결책을 확인하십시오.
## 관리형 호스팅
<Tip>
직접 Twenty를 실행하고 유지 관리하고 싶지 않으신가요? 인스턴스의 구축, 호스팅, 관리를 처음부터 끝까지 맡길 [공인 Twenty 호스팅 파트너](https://twenty.com/partners/list?categories=HOSTING\&ref=docs-docker-compose)를 찾아보세요. *(또는 저희 팀에 문의하세요: [contact@twenty.com](mailto:contact@twenty.com).)*
</Tip>

View File

@@ -0,0 +1,60 @@
---
title: 키 로테이션
icon: rotate
---
Twenty에는 서로 독립적인 키 계열이 두 가지 있습니다:
* **JWT 서명 키** — 비대칭 ES256 키 페어(`kid` 태그 사용)로, `core."signingKey"`에 저장되며 액세스/리프레시 토큰을 서명하고 검증하는 데 사용됩니다.
* **정지 상태 암호화 키** — OAuth 토큰, 애플리케이션 변수, 서명 키의 개인 키, 민감한 설정 값, `enc:v2:` 봉투 안의 TOTP 시크릿을 암호화하는 데 사용되는 `ENCRYPTION_KEY`입니다.
`APP_SECRET`은 하위 호환성을 위해 유지되는 레거시 시크릿입니다. `ENCRYPTION_KEY`가 설정되지 않은 경우 정지 상태 암호화/세션 쿠키 폴백 역할을 하며, 기존 HS256 액세스 토큰을 계속 검증합니다. 이는 사용 중단 예정입니다.
## JWT 서명 키
각 키는 `publicKey`(이전에 발급된 토큰을 검증할 수 있도록 무기한 보관), 암호화된 `privateKey`(해당 키가 현재 키일 때만 사용), `isCurrent` 플래그(한 번에 정확히 한 행만 true), 선택적인 `revokedAt`를 가집니다.
### 현재 키 회전
옵트인하려면 `SIGNING_KEY_ROTATION_DAYS` 를 설정하세요. 그러면 일일 cron 작업이 기존 키가 해당 기준값보다 오래되면 새로운 현재 키를 발급합니다. 이전 키는 *폐기되지 않으므로*, 해당 키로 서명된 토큰은 계속 검증됩니다. 자동 회전을 사용하지 않으려면 변수를 설정하지 않은 상태로 두세요.
<Note>자동 회전 기능은 v2.6+부터 제공됩니다.</Note>
### 키 폐기(유출 / 비상 시에만)
현재 키가 아닌 행에서 **Settings → Admin Panel → Signing keys → Revoke**를 수행합니다. 암호화된 개인 데이터를 삭제하고 `revokedAt`을 설정하며, 해당 `kid`로 서명된 모든 기존 토큰을 거부합니다.
## `ENCRYPTION_KEY` 회전
<Note>아래에 설명된 `secret-encryption:rotate` 커맨드는 v2.6+에서 제공됩니다.</Note>
모든 암호화된 값은 `enc:v2:\<keyId>:\<payload>` 형식으로 래핑됩니다. 여기서 `\<keyId>`는 원시 키에서 파생된 8자리 16진수 접두사입니다. 회전 작업은 온라인으로 수행되며, 중단 후 재개할 수 있습니다.
1. **새 키 생성**: `openssl rand -base64 32`.
2. `.env`에 **두 키를 나란히 설정**한 다음, 재시작합니다:
```ini
ENCRYPTION_KEY=NEW_VALUE
FALLBACK_ENCRYPTION_KEY=OLD_VALUE
```
새로 기록되는 데이터는 새 키를 사용하며, 기존 행은 폴백을 통해 계속 복호화됩니다.
3. **기존 행 재암호화**:
```bash
docker exec -it {server_container} yarn command:prod secret-encryption:rotate
```
이 커맨드는 여섯 개의 위치(`connected-account-tokens`, `application-variable`, `application-registration-variable`, `signing-key-private-keys`, `sensitive-config-storage`, `totp-secrets`)를 순회합니다. SQL 필터는 이미 새 `\<keyId>`로 암호화된 행을 건너뛰므로, 이 커맨드는 멱등성을 가집니다. 필요에 따라 중단하고 다시 실행해도 됩니다. 어떤 행이라도 실패하면 0이 아닌 코드로 종료되며, 재실행하여 재시도할 수 있습니다.
| 플래그 | 설명 |
| ---------------------------------------- | ---------------------------------------- |
| `-s, --site \<site>` | 단일 사이트로 범위를 제한합니다. |
| `-b, --batch-size \<n>` | 배치당 행 수(기본값 `200`, 최대 `5000`). |
| `-d, --dry-run` | 메모리에서 복호화 + 재암호화를 수행하고, `UPDATE`는 생략합니다. |
4. `--dry-run` 결과 남은 행이 0이면 **폴백을 제거**합니다. `FALLBACK_ENCRYPTION_KEY`를 삭제하고 재시작합니다.
## 레거시 `APP_SECRET` 지원
`ENCRYPTION_KEY`를 설정하지 않은 오래된 인스턴스는 정지 상태 암호화 키(및 이로부터 파생된 세션 쿠키 시크릿)로 `APP_SECRET`을 사용합니다. 이 경로는 하위 호환성을 위해 유지되지만 **사용 중단 예정**입니다. 전용 `ENCRYPTION_KEY`를 설정하고 위의 회전 절차를 따라 이를 사용하지 않는 방식으로 마이그레이션하세요. `APP_SECRET` 자체는 기존 HS256 액세스 토큰을 검증하는 데 계속 사용됩니다.

View File

@@ -0,0 +1,411 @@
---
title: 설정
icon: gear
---
# 구성 관리
<Warning>
**처음 설치하시나요?** [Docker Compose 설치 가이드](/l/ko/developers/self-host/capabilities/docker-compose)를 따라 Twenty를 실행하고, 이곳으로 돌아와 구성을 진행하세요.
</Warning>
Twenty는 다른 배포 요구에 맞추기 위해 **두 가지 구성 모드**를 제공합니다:
**관리자 패널 접근:** 관리자 권한이 있는 사용자만 (`canAccessFullAdminPanel: true`) 구성 인터페이스에 접근할 수 있습니다.
## 1. 관리자 패널 구성 (기본값)
```bash
IS_CONFIG_VARIABLES_IN_DB_ENABLED=true # default
```
설치 후 **대부분의 구성은 UI를 통해 이루어집니다:**
1. Twenty 인스턴스에 접근하십시오 (보통 `http://localhost:3000`)
2. **설정 / 관리자 패널 / 구성 변수**로 이동하세요
3. 통합, 이메일, 저장소 등을 구성하세요
4. 변경 사항은 즉시 적용됩니다 (멀티 컨테이너 배포의 경우 15초 이내)
<Warning>
**멀티 컨테이너 배포:** 데이터베이스 구성을 사용할 때 (`IS_CONFIG_VARIABLES_IN_DB_ENABLED=true`), 서버와 작업자 컨테이너 모두 동일한 데이터베이스에서 읽습니다. 관리자 패널의 변경은 둘 다 자동으로 영향을 미쳐 환경 변수를 컨테이너 간에 복제할 필요가 없습니다 (인프라 변수 제외).
</Warning>
**관리자 패널에서 구성할 수 있는 내용:**
* **인증** - Google/Microsoft OAuth, 비밀번호 설정
* **이메일** - SMTP 설정, 템플릿, 확인
* **저장소** - S3 구성, 로컬 저장 경로
* **통합** - Gmail, Google 캘린더, Microsoft 서비스
* **워크플로우 및 속도 제한** - 실행 제한, API 스로틀링
* **그리고 훨씬 더...**
![관리자 패널 구성 변수](/images/user-guide/setup/admin-panel-config-variables.png)
<Warning>
각 변수는 **설정 → 관리자 패널 → 구성 변수**의 관리자 패널에 설명과 함께 문서화되어 있습니다.
데이터베이스 연결(`PG_DATABASE_URL`), 서버 URL(`SERVER_URL`), 비밀 값(`ENCRYPTION_KEY`, `FALLBACK_ENCRYPTION_KEY`)과 같은 일부 인프라 설정은 `.env` 파일을 통해서만 구성할 수 있습니다.
[완전한 기술적 참조 →](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts)
</Warning>
## 암호화 키
Twenty는 환경 변수로만 설정할 수 있는 암호화 키를 두 개 사용합니다:
| 변수 | 목적 | 필수 |
| ------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `ENCRYPTION_KEY` | 휴지 상태의 비밀(OAuth 토큰, 애플리케이션 변수, 서명 키 개인 키, TOTP 비밀, 민감한 구성 값)을 암호화하는 데 사용되는 기본 키입니다. | 새로운 설치의 경우 예(레거시 설치는 대신 `APP_SECRET`에 의존할 수 있습니다 — 아래 참조) |
| `FALLBACK_ENCRYPTION_KEY` | 검증 전용 키입니다. 회전 중 기존 행을 계속 복호화할 수 있도록, *이전* `ENCRYPTION_KEY`로 설정합니다. | 회전 중에만 |
하위 호환을 위해 `ENCRYPTION_KEY`가 설정되지 않은 경우, Twenty는 휴지 상태 암호화에 대해 `APP_SECRET`을 대신 사용하여 기존 배포의 레거시 동작과 일치합니다. 새로운 설치에서는 항상 전용 `ENCRYPTION_KEY`를 설정해야 합니다.
`openssl rand -base64 32`로 값을 생성한 뒤 비밀 관리자, 봉인된 구성 등 안전한 위치에 저장하세요. `ENCRYPTION_KEY`를 분실하면 데이터베이스에 저장된 모든 비밀에 대한 접근을 잃게 됩니다.
중단 없이 `ENCRYPTION_KEY`를 회전하는 방법은 [키 회전 가이드](/l/ko/developers/self-host/capabilities/key-rotation)를 참고하세요.
## 2. 환경 전용 구성
```bash
IS_CONFIG_VARIABLES_IN_DB_ENABLED=false
```
**모든 구성이 `.env` 파일을 통해 관리됩니다:**
1. `.env` 파일에서 `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`로 설정하세요
2. 모든 구성 변수를 `.env` 파일에 추가하세요
3. 변경 사항이 적용되도록 컨테이너를 재시작하세요
4. 관리자 패널에서는 현재 값을 표시하며 수정할 수 없습니다
## 멀티 워크스페이스 모드
기본적으로 Twenty는 **단일 워크스페이스 모드**로 실행됩니다 — 조직에 하나의 CRM 인스턴스가 필요한 대부분의 자가 호스팅 배포에 적합합니다.
### 단일 워크스페이스 모드(기본값)
```bash
IS_MULTIWORKSPACE_ENABLED=false # default
```
* Twenty 인스턴스당 하나의 워크스페이스
* 첫 번째 사용자는 자동으로 전체 권한(`canImpersonate` 및 `canAccessFullAdminPanel`)을 가진 관리자가 됩니다
* 첫 번째 워크스페이스가 생성된 후에는 신규 가입이 비활성화됩니다
* 간단한 URL 구조: `https://your-domain.com`
### 멀티 워크스페이스 모드 활성화
```bash
IS_MULTIWORKSPACE_ENABLED=true
DEFAULT_SUBDOMAIN=app # default value
```
여러 독립적인 팀이 동일한 Twenty 인스턴스에서 자체 워크스페이스가 필요한 SaaS형 배포에서 멀티 워크스페이스 모드를 활성화하세요.
**단일 워크스페이스 모드와의 주요 차이점:**
* 동일한 인스턴스에서 여러 워크스페이스를 생성할 수 있습니다
* 각 워크스페이스는 자체 서브도메인을 갖습니다 (예: `sales.your-domain.com`, `marketing.your-domain.com`)
* 사용자는 `{DEFAULT_SUBDOMAIN}.your-domain.com`에서 가입하고 로그인합니다 (예: `app.your-domain.com`)
* 관리자 권한이 자동으로 부여되지 않습니다 — 각 워크스페이스의 첫 번째 사용자는 일반 사용자입니다
* 서브도메인 및 사용자 지정 도메인과 같은 워크스페이스 전용 설정이 워크스페이스 설정에서 제공됩니다
<Warning>
**환경 전용 설정:** `IS_MULTIWORKSPACE_ENABLED`는 `.env` 파일을 통해서만 구성할 수 있으며 재시작이 필요합니다. 관리자 패널을 통해 변경할 수 없습니다.
</Warning>
### 멀티 워크스페이스를 위한 DNS 구성
멀티 워크스페이스 모드를 사용할 때, 동적 서브도메인 생성을 허용하도록 와일드카드 레코드로 DNS를 구성하세요:
```
*.your-domain.com -> your-server-ip
```
이렇게 하면 수동 DNS 구성 없이 새 워크스페이스에 대한 서브도메인 라우팅이 자동으로 활성화됩니다.
### 워크스페이스 생성 제한
멀티 워크스페이스 모드에서, 누가 새 워크스페이스를 생성할 수 있는지 제한하고 싶을 수 있습니다:
```bash
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
```
활성화되면 `canAccessFullAdminPanel` 권한이 있는 사용자만 추가 워크스페이스를 생성할 수 있습니다. 사용자는 초기 가입 과정에서 첫 번째 워크스페이스를 여전히 생성할 수 있습니다.
## Gmail & Google 캘린더 통합
### Google 클라우드 프로젝트 생성
1. [Google Cloud Console](https://console.cloud.google.com/)로 이동하세요
2. 새 프로젝트를 생성하거나 기존 프로젝트를 선택하세요
3. 이 API들을 활성화하세요:
* [Gmail API](https://console.cloud.google.com/apis/library/gmail.googleapis.com)
* [Google 캘린더 API](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com)
* [People API](https://console.cloud.google.com/apis/library/people.googleapis.com)
### OAuth 구성
1. [자격 증명](https://console.cloud.google.com/apis/credentials)으로 이동하세요
2. OAuth 2.0 클라이언트 ID를 생성하세요
3. 이러한 리디렉션 URI를 추가하세요:
* `https://{your-domain}/auth/google/redirect` (SSO용)
* `https://{your-domain}/auth/google-apis/get-access-token` (통합용)
### Twenty에서 구성하기
1. **설정 → 관리자 패널 → 구성 변수**로 이동하세요
2. **Google 인증** 섹션을 찾으세요
3. 다음 변수를 설정하세요:
* `MESSAGING_PROVIDER_GMAIL_ENABLED=true`
* `CALENDAR_PROVIDER_GOOGLE_ENABLED=true`
* `AUTH_GOOGLE_CLIENT_ID={client-id}`
* `AUTH_GOOGLE_CLIENT_SECRET={client-secret}`
* `AUTH_GOOGLE_CALLBACK_URL=https://{your-domain}/auth/google/redirect`
* `AUTH_GOOGLE_APIS_CALLBACK_URL=https://{your-domain}/auth/google-apis/get-access-token`
<Warning>
**환경 전용 모드:** `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`로 설정한 경우, `.env` 파일에 이러한 변수를 추가하세요.
</Warning>
**필요한 범위** (자동 구성됨):
[관련 소스 코드 보기](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes.ts#L4-L10)
* `https://www.googleapis.com/auth/calendar.events`
* `https://www.googleapis.com/auth/gmail.readonly`
* `https://www.googleapis.com/auth/profile.emails.read`
### 앱이 테스트 모드인 경우
앱이 테스트 모드인 경우, 프로젝트에 테스트 사용자를 추가해야 합니다.
[OAuth 승인 화면](https://console.cloud.google.com/apis/credentials/consent)에서 "테스트 사용자" 섹션에 테스트 사용자를 추가하세요.
## Microsoft 365 통합
<Warning>
사용자는 캘린더 및 메시징 API를 사용하려면 [Microsoft 365 라이선스](https://admin.microsoft.com/Adminportal/Home)를 보유해야 합니다. 없이는 Twenty에서 계정을 동기화할 수 없습니다.
</Warning>
### Microsoft Azure에 프로젝트 생성
[Microsoft Azure](https://portal.azure.com/#view/Microsoft_AAD_IAM/AppGalleryBladeV2)에서 프로젝트를 생성하고 자격 증명을 확보해야 합니다.
### API 활성화
Microsoft Azure 콘솔에서 "권한"에서 다음 API를 활성화하세요:
* Microsoft Graph: Mail.ReadWrite
* Microsoft Graph: Mail.Send
* Microsoft Graph: Calendars.Read
* Microsoft Graph: User.Read
* Microsoft Graph: openid
* Microsoft Graph: email
* Microsoft Graph: profile
* Microsoft Graph: offline_access
<Note>
"Mail.ReadWrite"와 "Mail.Send"는 워크플로우 작업을 통해 이메일을 보내려는 경우에만 필수입니다. 이메일 수신만 원하시면 대신 "Mail.Read"를 사용하세요.
</Note>
<Note>
워크플로우 작업을 사용하여 캘린더 이벤트를 생성하려면 "Calendars.ReadWrite"가 필수입니다. 캘린더 이벤트만 동기화하려면 "Calendars.Read"를 사용하세요.
</Note>
### 인가된 리디렉션 URI
프로젝트에 다음 리디렉션 URI를 추가해야 합니다:
* Microsoft SSO를 사용하려면 `https://{your-domain}/auth/microsoft/redirect`
* `https://{your-domain}/auth/microsoft-apis/get-access-token`
### Twenty에서 구성하기
1. **설정 → 관리자 패널 → 구성 변수**로 이동하세요
2. **Microsoft 인증** 섹션을 찾으세요
3. 다음 변수를 설정하세요:
* `MESSAGING_PROVIDER_MICROSOFT_ENABLED=true`
* `CALENDAR_PROVIDER_MICROSOFT_ENABLED=true`
* `AUTH_MICROSOFT_ENABLED=true`
* `AUTH_MICROSOFT_CLIENT_ID={client-id}`
* `AUTH_MICROSOFT_CLIENT_SECRET={client-secret}`
* `AUTH_MICROSOFT_CALLBACK_URL=https://{your-domain}/auth/microsoft/redirect`
* `AUTH_MICROSOFT_APIS_CALLBACK_URL=https://{your-domain}/auth/microsoft-apis/get-access-token`
<Warning>
**환경 전용 모드:** `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`로 설정한 경우, `.env` 파일에 이러한 변수를 추가하세요.
</Warning>
### 범위 구성
[관련 소스 코드 보기](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes.ts#L2-L9)
* 'openid'
* '이메일'
* '프로필'
* 'offline_access'
* 'Mail.ReadWrite'
* 'Mail.Send'
* 'Calendars.Read'
### 앱이 테스트 모드인 경우
앱이 테스트 모드인 경우, 프로젝트에 테스트 사용자를 추가해야 합니다.
"사용자 및 그룹" 섹션에 테스트 사용자를 추가하세요.
## 캘린더 및 메시징을 위한 배경 작업
Gmail, Google 캘린더 또는 Microsoft 365 통합을 구성한 후, 데이터를 동기화하는 배경 작업을 시작해야 합니다.
작업자 컨테이너에 다음 주기 작업을 등록하세요:
```bash
# from your worker container
yarn command:prod cron:messaging:messages-import
yarn command:prod cron:messaging:message-list-fetch
yarn command:prod cron:calendar:calendar-event-list-fetch
yarn command:prod cron:calendar:calendar-events-import
yarn command:prod cron:messaging:ongoing-stale
yarn command:prod cron:calendar:ongoing-stale
yarn command:prod cron:workflow:automated-cron-trigger
```
## 이메일 구성
1. **설정 → 관리자 패널 → 구성 변수**로 이동하세요
2. **이메일** 섹션을 찾으세요
3. SMTP 설정을 구성하세요:
<Tabs>
<Tab title="Gmail">
[App Password](https://support.google.com/accounts/answer/185833)를 프로비저닝해야 합니다.
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=smtp.gmail.com
* EMAIL_SMTP_PORT=465
* EMAIL_SMTP_USER=gmail_email_address
* EMAIL_SMTP_PASSWORD='gmail_app_password'
</Tab>
<Tab title="오피스365">
2단계 인증을 사용 중인 경우, [앱 비밀번호](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9)를 발급받아야 합니다.
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=smtp.office365.com
* EMAIL_SMTP_PORT=587
* EMAIL_SMTP_USER=office365_email_address
* EMAIL_SMTP_PASSWORD='office365_password'
</Tab>
<Tab title="smtp4dev">
**smtp4dev**는 개발 및 테스트를 위한 가상의 SMTP 이메일 서버입니다.
* smtp4dev 이미지를 실행하세요: `docker run --rm -it -p 8090:80 -p 2525:25 rnwood/smtp4dev`
* smtp4dev UI에 여기에 접근하세요: [http://localhost:8090](http://localhost:8090)
* 다음 변수를 설정하세요:
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=localhost
* EMAIL_SMTP_PORT=2525
</Tab>
</Tabs>
<Warning>
**환경 전용 모드:** `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`로 설정한 경우, `.env` 파일에 이러한 변수를 추가하세요.
</Warning>
## S3 저장소
<Warning>
기본적으로 Twenty는 업로드된 파일을 로컬 파일 시스템에 저장합니다. 프로덕션 배포에서는 S3 또는 S3 호환 서비스(MinIO, DigitalOcean Spaces 등)를 사용하세요. 컨테이너 재시작 시에도 파일이 유지되고, 여러 서버 인스턴스에 걸쳐 확장될 수 있도록 하기 위함입니다.
</Warning>
`STORAGE_TYPE=S_3`를 설정하고 관리자 패널 또는 `.env`를 통해 `STORAGE_S3_*` 변수를 구성하세요. 전체 S3 변수 목록은 [config-variables.ts 참조](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts)를 확인하세요.
CORS에 의존하는 기능(예: 브라우저 내 파일 다운로드)과 함께 S3를 사용할 때에는, 버킷의 CORS 구성에서 Twenty 프런트엔드 오리진을 허용하도록 하세요.
## 로직 함수 및 코드 인터프리터
Twenty는 워크플로를 위한 로직 함수와 AI 데이터 분석을 위한 코드 인터프리터를 지원합니다. 두 기능 모두 사용자 제공 코드를 실행하며, 보안을 위해 명시적인 구성이 필요합니다.
### 보안 기본값
**프로덕션 (NODE_ENV=production):** 로직 함수와 코드 인터프리터는 기본값이 **비활성화됨**입니다. 이러한 기능이 필요하다면 `LOGIC_FUNCTION_TYPE` 및 `CODE_INTERPRETER_TYPE`로 명시적으로 활성화해야 합니다.
**개발 (NODE_ENV=development):** 로컬에서 실행할 때 편의를 위해 둘 다 기본값이 **LOCAL**입니다.
<Warning>
**보안 공지:** 로컬 드라이버 (`LOGIC_FUNCTION_TYPE=LOCAL` 또는 `CODE_INTERPRETER_TYPE=LOCAL`)는 샌드박싱 없이 호스트의 Node.js 프로세스에서 코드를 직접 실행합니다. 개발 환경에서 신뢰할 수 있는 코드에만 사용해야 합니다. 신뢰할 수 없는 코드를 처리하는 프로덕션 배포에서는 `LOGIC_FUNCTION_TYPE=LAMBDA` 또는 `CODE_INTERPRETER_TYPE=E2B`(샌드박싱 적용)을 사용하거나 비활성화 상태로 유지하세요.
</Warning>
### 로직 함수 - 사용 가능한 드라이버
| 드라이버 | 환경 변수 | 사용 사례 | 보안 수준 |
| ------ | ------------------------------ | ------------------------- | --------------- |
| 비활성화 | `LOGIC_FUNCTION_TYPE=DISABLED` | 로직 함수를 완전히 비활성화 | 해당 없음 |
| 로컬 | `LOGIC_FUNCTION_TYPE=LOCAL` | 개발 및 신뢰할 수 있는 환경 | 낮음 (샌드박싱 없음) |
| Lambda | `LOGIC_FUNCTION_TYPE=LAMBDA` | 신뢰할 수 없는 코드를 처리하는 프로덕션 환경 | 높음 (하드웨어 수준 격리) |
### 로직 함수 - 권장 구성
**개발:**
```bash
LOGIC_FUNCTION_TYPE=LOCAL # default when NODE_ENV=development
```
**프로덕션(AWS):**
```bash
LOGIC_FUNCTION_TYPE=LAMBDA
LOGIC_FUNCTION_LAMBDA_REGION=us-east-1
LOGIC_FUNCTION_LAMBDA_ROLE=arn:aws:iam::123456789:role/your-lambda-role
LOGIC_FUNCTION_LAMBDA_ACCESS_KEY_ID=your-access-key
LOGIC_FUNCTION_LAMBDA_SECRET_ACCESS_KEY=your-secret-key
```
**로직 함수를 비활성화하려면:**
```bash
LOGIC_FUNCTION_TYPE=DISABLED # default when NODE_ENV=production
```
### 코드 인터프리터 - 사용 가능한 드라이버
| 드라이버 | 환경 변수 | 사용 사례 | 보안 수준 |
| ---- | -------------------------------- | ------------------ | ------------- |
| 비활성화 | `CODE_INTERPRETER_TYPE=DISABLED` | AI 코드 실행 비활성화 | 해당 없음 |
| 로컬 | `CODE_INTERPRETER_TYPE=LOCAL` | 개발 전용 | 낮음 (샌드박싱 없음) |
| E2B | `CODE_INTERPRETER_TYPE=E_2_B` | 샌드박스 실행을 사용하는 프로덕션 | 높음 (격리된 샌드박스) |
<Note>
`LOGIC_FUNCTION_TYPE=DISABLED` 또는 `CODE_INTERPRETER_TYPE=DISABLED`를 사용하는 경우, 모든 실행 시도는 오류를 반환합니다. 이러한 기능 없이 Twenty를 실행하려는 경우 유용합니다.
</Note>
## 별도 호스트에서 동작하는 API와 프런트엔드
백엔드가 프런트엔드를 제공하지 않는 경우에만 해당됩니다. 동일 출처
배포의 경우 여기에서 추가로 설정할 내용이 없습니다.
API와 통신하는 모든 브라우저 오리진을 쉼표로 구분하여 선언하세요. `SERVER_URL`
과 `FRONTEND_URL`은 이미 신뢰된 상태입니다. 브라우저가 선언되지 않은 오리진에서 서버를 호출하면,
서버는 경고를 로그에 기록합니다.
```bash
AUTH_COOKIE_ALLOWED_ORIGINS=https://app.example.com
```
<Warning>
프런트엔드는 모든 요청에 자격 증명을 함께 보내고, 브라우저는 선언되지 않은 오리진에서 오는 자격 증명 포함 응답을 거부하므로, 이 값을 설정하기 전까지 앱이 로드되지 않습니다.
</Warning>
두 호스트가 서로 다른 등록 가능한 도메인(단순히 서로 다른 서브도메인이 아닌 경우)에 있다면, `AUTH_COOKIE_SAME_SITE=none`도 설정해야 하며, 이때는 HTTPS가 필요합니다.
멀티 워크스페이스가 활성화된 경우, 여기에는 모든 워크스페이스 서브도메인을 나열하지 마세요.
대신, 각 워크스페이스 호스트 이름에서 API 경로(`/graphql`, `/metadata`, `/rest`, `/auth/`,
`/client-config`, `/file`)를 백엔드로 라우팅하여 모든 워크스페이스가 동일 오리진을 유지하도록 하세요. Twenty Cloud는 이렇게 동작합니다.

View File

@@ -0,0 +1,254 @@
---
title: 문제 해결
icon: wrench
---
## 문제 해결
개발 환경을 설정하거나 인스턴스를 업그레이드하거나 자체 호스팅하는 도중 문제가 발생하는 경우, 여기에는 일반적인 문제들에 대한 몇 가지 해결책이 있습니다.
### 셀프 호스팅
#### 첫 설치 시 `사용자 "postgres"에 대한 비밀번호 인증 실패`라는 메시지가 표시됨
⚠️ 경고: 다음 단계는 데이터베이스 데이터를 **영구적으로 삭제합니다!** ⚠️
중요한 데이터가 없는 새 설치인 경우에만 진행하십시오.
Twenty를 처음 설치할 때, 기본 데이터베이스 비밀번호를 변경하고 싶을 수 있습니다.
첫 설치 시 설정한 비밀번호는 데이터베이스 볼륨에 영구 저장됩니다. 나중에 기존의 볼륨을 제거하지 않고 설정에서 비밀번호를 변경하려고 하면, 데이터베이스에서 원래 비밀번호를 사용하고 있기 때문에 인증 오류가 발생할 수 있습니다.
⚠️ 경고: 다음 단계는 데이터베이스 데이터를 **영구적으로 삭제합니다!** ⚠️ 경고: 다음 단계는 데이터베이스 데이터를 **영구적으로 삭제합니다!** ⚠️
중요한 데이터가 없는 새 설치인 경우에만 진행하십시오.
`PG_DATABASE_PASSWORD`를 업데이트하려면 다음을 수행해야 합니다:
```sh
# Update the PG_DATABASE_PASSWORD in .env
docker compose down --volumes
docker compose up -d
```
#### CR 줄바꿈이 발견되었습니다 [Windows]
이는 Windows 줄 바꿈 문자와 Git 구성의 조합으로 인해 발생합니다. 다음 명령을 실행해 보세요:
```
git config --global core.autocrlf false
```
그런 다음 저장소를 삭제하고 다시 클론하세요.
#### 메타데이터 스키마 누락
Twenty 설치 중에 적절한 스키마, 확장, 사용자를 사용하여 postgres 데이터베이스를 프로비저닝해야 합니다.
프로비저닝이 성공적으로 이루어지면 데이터베이스에 `기본` 및 `메타데이터` 스키마가 있어야 합니다.
그렇지 않다면, 컴퓨터에서 둘 이상의 PostgreSQL 인스턴스가 실행되고 있지 않은지 확인하십시오.
#### 모듈 'twenty-emails' 또는 해당 형식 선언을 찾을 수 없습니다.
데이터베이스 초기화를 실행하기 전에 `twenty-emails` 패키지(`npx nx run twenty-emails:build`)를 빌드해야 합니다.
#### twenty-x 패키지가 누락됨
루트 디렉토리에서 yarn을 실행한 다음 `npx nx server:dev twenty-server` 를 실행하십시오. 여전히 작동하지 않으면 누락된 패키지를 수동으로 빌드해보세요.
#### 저장 시 린트가 작동하지 않음
Oxc 확장 프로그램(`oxc.oxc-vscode`)이 설치된 상태에서는 기본 설정으로 작동해야 합니다. 이렇게 해도 작동하지 않는 경우, VS Code 설정(개발 컨테이너 범위)에 다음을 추가해 보십시오:
```
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "explicit"
}
```
#### `npx nx start` 또는 `npx nx start twenty-front`를 실행하는 동안 메모리 부족 오류가 발생합니다
`npx nx start` 대신 필요한 서비스만 실행하십시오. 예를 들어, 서버에서 작업하는 경우, `npx nx worker twenty-server`만 실행하십시오.
**작동하지 않는 경우:**
WSL에서 `npx nx run twenty-server:start`만 실행하려고 했으나 아래의 메모리 오류로 실패할 경우:
`치명적인 오류: 효과적인 마크-컴팩트 임계값 인근 할당 실패 - JavaScript 힙 메모리 부족`
해결 방법으로, 터미널에서 다음 명령을 실행하거나 `.bashrc` 프로파일에 추가하여 자동으로 적용되도록 할 수 있습니다:
`export NODE_OPTIONS="--max-old-space-size=8192"`
\--max-old-space-size=8192 플래그는 Node.js 힙의 상한선을 8GB로 설정합니다. 사용량은 애플리케이션 수요에 따라 조정됩니다.
참고: https://stackoverflow.com/questions/56982005/where-do-i-set-node-options-max-old-space-size-2048
**작동하지 않는 경우:**
어떤 프로세스가 머신의 RAM 대부분을 사용하고 있는지 조사하십시오. Twenty에서는 일부 VS Code 확장이 많은 RAM을 사용하고 있음을 발견하여, 이를 일시적으로 비활성화했습니다.
**작동하지 않는 경우:**
머신을 다시 시작하면 유령 프로세스를 정리하는 데 도움이 됩니다.
#### `npx nx start`를 실행할 때 로그에 이상한 [0]과 [1]이 표시됨
이는 `npx nx start` 명령이 내부적으로 더 많은 명령을 실행하기 때문에 예상된 것입니다.
#### 이메일이 전송되지 않음
대부분의 경우, 이는 `worker`가 백그라운드에서 실행되지 않기 때문입니다. 실행해 보세요
```
npx nx worker twenty-server
```
#### Microsoft 365 계정을 Twenty에 연결할 수 없습니다
대부분의 경우, 관리자님께서 계정에 대한 Microsoft 365 라이센스를 활성화하지 않았기 때문입니다. [https://admin.microsoft.com/](https://admin.microsoft.com/Adminportal/Home)에서 확인하십시오.
`AADSTS50020` 오류 코드가 표시되는 경우, 개인 Microsoft 계정을 사용하고 있을 가능성이 높습니다. 이는 아직 지원되지 않습니다. 추가 정보는 [여기](https://learn.microsoft.com/fr-fr/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist)에서 확인하십시오
#### `yarn`을 실행하는 동안 콘솔에 경고가 나타납니다
경고는 `package.json`에 명시적으로 나타나지 않는 추가 종속성을 끌어오는 것에 대한 정보입니다. 중대한 오류가 나타나지 않는 한 모든 것이 예상대로 작동해야 합니다.
#### 사용자가 로그인 페이지에 접근할 때, 작업 공간에 접근하려는 권한 없는 사용자에 대한 오류가 로그에 나타납니다
로그아웃된 상태에서 사용자의 신원이 확인되지 않았기 때문에, 해당 사용자는 권한이 없으며 이는 예상된 동작입니다.
#### 작업자가 작동 중인지 확인하는 방법은?
* [webhook-test.com](https://webhook-test.com/)으로 이동하여 **고유한 웹훅 URL**을 복사하십시오.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-test.jpg" alt="웹훅 테스트" />
</div>
* Twenty 앱을 열고 `/settings`로 이동하여 화면 왼쪽 하단에 있는 **고급** 토글을 활성화하십시오.
* 새 웹훅 생성.
* **고유한 웹훅 URL**을 Twenty의 **엔드포인트 URL** 필드에 붙여넣습니다. **필터**를 `회사`와 `생성됨`으로 설정하십시오.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-settings.jpg" alt="웹훅 설정" />
</div>
* `/objects/companies`로 이동하여 새 회사 레코드를 만드십시오.
* [webhook-test.com](https://webhook-test.com/)으로 돌아가 새 **POST 요청**이 수신되었는지 확인하십시오.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-test-result.jpg" alt="웹훅 테스트 결과" />
</div>
* **POST 요청**이 수신된 경우, 작업자가 성공적으로 실행 중입니다. 그렇지 않으면, 작업자에 대한 문제 해결이 필요합니다.
#### 프런트엔드 시작에 실패하고 다음 오류를 반환합니다: TS5042: 명령줄에서 소스 파일과 옵션 'project'를 함께 사용할 수 없습니다
아래 예시와 같이 `packages/twenty-ui/vite-config.ts`에서 checker 플러그인을 주석 처리하십시오:
```
plugins: [
react({ jsxImportSource: 'react' }),
tsconfigPaths(),
svgr(),
dts(dtsConfig),
// checker(checkersConfig),
wyw({
include: [
'**/OverflowingTextWithTooltip.tsx',
'**/Chip.tsx',
'**/Tag.tsx',
'**/Avatar.tsx',
'**/AvatarChip.tsx',
],
babelOptions: {
presets: ['@babel/preset-typescript', '@babel/preset-react'],
},
}),
],
```
#### 관리자 패널에 액세스할 수 없음
관리자 패널에 액세스하기 위해 데이터베이스 컨테이너에서 `UPDATE core."user" SET "canAccessFullAdminPanel" = TRUE WHERE email = 'you@yourdomain.com';`를 실행하십시오.
#### 워크플로우를 실행하면 다음 오류로 실행이 실패합니다: "로직 함수 실행이 비활성화되었습니다. 활성화하려면 LOGIC_FUNCTION_TYPE을 LOCAL 또는 LAMBDA로 설정하세요."
프로덕션 환경에서는 로직 함수가 기본적으로 비활성화되어 있습니다. 이를 활성화하려면 `LOGIC_FUNCTION_TYPE` 환경 변수를 `LOCAL` 또는 `LAMBDA`로 설정하세요. 이는 환경 변수를 통해서나 관리자 패널의 데이터베이스 변수를 통해 구성할 수 있습니다. 자세한 내용은 [로직 함수 설정 가이드](/l/ko/developers/self-host/capabilities/setup#logic-functions-available-drivers)를 참조하세요.
#### AI 채팅에 메시지를 입력하면 바로 응답하지 않고, 답변을 보려면 페이지를 새로고침해야 합니다
이는 역방향 프록시에 스트림 기반 API 응답을 위한 구성이 누락되어 있다는 의미입니다. 아래는 예시 Nginx 구성입니다:
```
location ~* ^/api/.*stream|\/graphql\/stream {
proxy_pass http://twenty_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache off;
gzip off;
#chunked_transfer_encoding off;
add_header X-Accel-Buffering no always;
}
```
### 1-클릭 Docker Compose
#### 로그인할 수 없음
설정 후 로그인할 수 없는 경우:
1. 다음 명령어를 실행하십시오:
```bash
docker exec -it twenty-server-1 yarn
docker exec -it twenty-server-1 npx nx database:reset --configuration=no-seed
```
2. Docker 컨테이너를 다시 시작하십시오:
```bash
docker compose down
docker compose up -d
```
`database:reset` 명령은 데이터베이스를 완전히 삭제하고 처음부터 다시 생성한다는 점에 유의하십시오.
#### 리버스 프록시 뒤에서 연결 문제
Twenty를 리버스 프록시 뒤에서 실행 중이며 연결 문제가 있는 경우:
1. **SERVER_URL 확인:**
`.env` 파일의 `SERVER_URL`이 SSL이 활성화된 경우 외부 액세스 URL과 `https`까지 일치하는지 확인하십시오.
2. **리버스 프록시 설정 확인:**
* 리버스 프록시가 Twenty 서버로 요청을 정확히 전달하는지 확인하십시오.
* `X-Forwarded-For`, `X-Forwarded-Proto`와 같은 헤더가 적절히 설정되어 있는지 확인하십시오.
3. **서비스 재시작:**
변경 후, 리버스 프록시와 Twenty 컨테이너를 모두 다시 시작하십시오.
#### 이미지 업로드 시 권한 거부 오류 발생
호스트의 데이터 폴더 소유권을 루트에서 다른 사용자 및 그룹으로 전환하면 이 문제가 해결됩니다.
#### 워크플로에서 Logic 함수를 테스트하는 동안 발생하는 '파일을 찾을 수 없음' 오류
누락된 종속성 문제를 해결하려면 twenty-server 컨테이너에서 `yarn command:prod application:rebuild-default-deps` 명령을 실행하세요.
## 도움 받기
이 가이드에 다루지 않은 문제를 겪는 경우:
* 로그 확인:
컨테이너 로그에서 오류 메시지 확인:
```bash
docker compose logs
```
* 커뮤니티 지원:
[Twenty 커뮤니티](https://github.com/twentyhq/twenty/issues)나 [지원 채널](https://discord.gg/cx5n4Jzs57)에 문의하십시오.

View File

@@ -0,0 +1,106 @@
---
title: 업그레이드 가이드
icon: arrow-up-right-dots
---
## 일반 가이드라인
**업그레이드 프로세스를 시작하기 전에 항상 데이터베이스를 백업하십시오** 다음 명령을 실행하세요:
```bash
docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql
```
백업에서 복원하려면:
```bash
cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}
```
Docker Compose를 사용하는 경우 다음 단계를 따르십시오:
1. Twenty 중지: `docker compose down`
2. `docker-compose.yml` 옆에 있는 `.env` 파일에서 `TAG` 값을 변경하십시오
3. Twenty 시작: `docker compose up -d`
서버는 시작 시 필요한 모든 업그레이드 마이그레이션을 자동으로 실행합니다. 수동 명령은 필요하지 않습니다.
## v2.34+로 업그레이드 — PostgreSQL 15 이상 필요
Twenty v2.34에는 PostgreSQL 15 이상이 필요합니다. 공식 Docker Compose 구성은 PostgreSQL 16을 사용합니다. 인스턴스가 외부에서 관리되는 데이터베이스에 연결되는 경우 v2.34 서버를 시작하기 전에 해당 데이터베이스를 업그레이드하세요.
## 교차 버전 업그레이드(v1.23+)
**v1.23**부터 Twenty는 교차 버전 업그레이드를 지원합니다. 지원되는 어떤 버전에서든 각 중간 버전을 거치지 않고 최신 릴리스로 바로 이동할 수 있습니다.
예를 들어, v1.23에서 v2.0으로 바로 업그레이드하는 것이 완전히 지원됩니다.
## v2.5+로 업그레이드 — 저장 상태 암호화 엔벨로프
**v2.5**부터 Twenty는 저장 상태의 시크릿(OAuth 토큰, 애플리케이션 변수, 서명 키의 개인 키, 민감한 설정값, TOTP 시크릿)을 버전이 지정된 `enc:v2:` 엔벨로프에 담아, `ENCRYPTION_KEY`(또는 `ENCRYPTION_KEY`가 설정되지 않은 경우 `APP_SECRET`)로 암호화해 저장합니다.
v2.5에서 첫 부팅 시, 기존 행을 새로운 엔벨로프에 백필하는 속도가 느린 업그레이드 명령이 실행됩니다. 이는 멱등적이어서 — 서버를 중단했다가 다시 시작해도 중단된 지점부터 재개되지만 — 대규모 데이터베이스에서는 시간이 오래 걸릴 수 있습니다. `upgrade:status`로 진행 상황을 모니터링할 수 있습니다.
백필이 처음부터 해당 키로 행을 기록할 수 있도록, v2.5 업그레이드 **이전에** 전용 `ENCRYPTION_KEY`를 설정해야 합니다. 백필 이후에 키를 변경하려면 [키 회전](/l/ko/developers/self-host/capabilities/key-rotation)이 필요합니다.
## 시크릿 및 서명 키 회전
`ENCRYPTION_KEY` 회전, JWT 서명 키 회전, 유출된 서명 키 폐기와 같은 일상 운영 작업에 대해서는 전용 [키 회전 가이드](/l/ko/developers/self-host/capabilities/key-rotation)를 참조하세요.
## 업그레이드 상태 확인
`upgrade:status` 명령을 사용하면 인스턴스 및 워크스페이스 마이그레이션의 현재 상태를 확인할 수 있습니다. 업그레이드 문제를 디버깅하거나 지원 요청을 제출할 때 유용합니다.
서버 컨테이너에서 실행하십시오:
```bash
docker exec -it {server_container_name_or_id} yarn command:prod upgrade:status
```
출력 예:
```sh
APP_VERSION: v1.23.0
Instance
Inferred version: 1.23.0
Latest command: 1.23.0_DropWorkspaceVersionColumnFastInstanceCommand_1785000000000
Status: Up to date
Executed by: v1.23.0
At: 2026-04-16T11:43:58.823Z
Workspace
Apple (20202020-1c25-4d02-bf25-6aeccf7ea419)
Inferred version: 1.23.0
Latest command: 1.23.0_UpdateGlobalObjectContextCommandMenuItemsCommand_1780000005000
Status: Up to date
Executed by: v1.23.0
At: 2026-04-16T11:44:09.361Z
Summary
Instance: Up to date
Workspaces: 1 up to date, 0 behind, 0 failed (1 total)
```
### 옵션
| 플래그 | 설명 |
| ------------------------- | ---------------------------------------- |
| `-w, --workspace-id <id>` | 특정 워크스페이스로 필터링합니다. 여러 번 지정할 수 있습니다. |
| `-f, --failed-only` | 최신 상태의 워크스페이스는 숨기고, 뒤처졌거나 실패한 항목만 표시합니다. |
## 문제 해결
일부 워크스페이스에서 업그레이드가 실패하면 서버는 실패한 단계 이후로 진행하지 않습니다. 서버를 다시 시작하면(`docker compose up -d`) 중단된 지점부터 업그레이드를 다시 시도합니다.
문제를 빠르게 식별하려면 다음을 실행하십시오:
```bash
docker exec -it {server_container_name_or_id} yarn command:prod upgrade:status --failed-only
```
이는 뒤처졌거나 실패한 워크스페이스만 표시하고 각 실패에 대한 오류 메시지도 함께 표시합니다.
## v1.23 이전
인스턴스가 v1.23보다 오래된 경우, v1.23에 도달할 때까지 각 주요 태그 버전(v1.6에서 v1.7, 이어서 v1.7에서 v1.8 등)을 순차적으로 업그레이드해야 합니다. 그 이후에는 최신 버전으로 바로 업그레이드할 수 있습니다.

View File

@@ -0,0 +1,26 @@
---
title: 셀프 호스팅
description: 자체 인프라에 Twenty를 배포하고 관리하세요.
---
<Frame>
<img src="/images/user-guide/what-is-twenty/20.png" alt="AI" />
</Frame>
## 개요
Twenty는 자체 인프라에서 셀프 호스팅할 수 있어 데이터와 배포에 대해 완전한 제어권을 가질 수 있습니다.
## 왜 셀프 호스팅인가요?
* **데이터 소유권**: 모든 CRM 데이터를 자체 서버에 보관하세요
* **컴플라이언스**: 데이터 상주에 대한 규제 요구사항을 준수하세요
* **커스터마이징**: 플랫폼을 수정하고 확장할 수 있는 완전한 접근 권한
## 시작하기
<CardGroup cols={2}>
<Card title="Docker Compose" icon="docker" href="/l/ko/developers/self-host/capabilities/docker-compose">
Docker로 빠르게 설정
</Card>
</CardGroup>