@intlayer/docs 9.0.0-canary.10 → 9.0.0-canary.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_CMS.md +16 -1
- package/docs/ar/releases/v9.md +58 -1
- package/docs/ar/self_hosting.md +349 -0
- package/docs/bn/intlayer_CMS.md +570 -0
- package/docs/bn/releases/v9.md +358 -0
- package/docs/cs/releases/v9.md +358 -0
- package/docs/de/intlayer_CMS.md +117 -1
- package/docs/de/releases/v9.md +61 -1
- package/docs/de/self_hosting.md +349 -0
- package/docs/en/intlayer_CMS.md +171 -1
- package/docs/en/releases/v9.md +45 -2
- package/docs/en/self_hosting.md +349 -0
- package/docs/en-GB/intlayer_CMS.md +16 -1
- package/docs/en-GB/releases/v9.md +47 -2
- package/docs/en-GB/self_hosting.md +349 -0
- package/docs/es/intlayer_CMS.md +117 -1
- package/docs/es/releases/v9.md +61 -1
- package/docs/es/self_hosting.md +349 -0
- package/docs/fr/intlayer_CMS.md +117 -1
- package/docs/fr/releases/v9.md +61 -1
- package/docs/fr/self_hosting.md +349 -0
- package/docs/hi/intlayer_CMS.md +16 -1
- package/docs/hi/releases/v9.md +59 -1
- package/docs/hi/self_hosting.md +349 -0
- package/docs/id/releases/v9.md +31 -1
- package/docs/id/self_hosting.md +349 -0
- package/docs/it/intlayer_CMS.md +117 -1
- package/docs/it/releases/v9.md +61 -1
- package/docs/it/self_hosting.md +349 -0
- package/docs/ja/intlayer_CMS.md +191 -10
- package/docs/ja/releases/v9.md +31 -1
- package/docs/ja/self_hosting.md +349 -0
- package/docs/ko/intlayer_CMS.md +189 -6
- package/docs/ko/releases/v9.md +30 -1
- package/docs/ko/self_hosting.md +349 -0
- package/docs/nl/releases/v9.md +358 -0
- package/docs/pl/intlayer_CMS.md +16 -1
- package/docs/pl/releases/v9.md +58 -1
- package/docs/pl/self_hosting.md +349 -0
- package/docs/pt/intlayer_CMS.md +117 -1
- package/docs/pt/releases/v9.md +61 -1
- package/docs/pt/self_hosting.md +349 -0
- package/docs/ru/intlayer_CMS.md +196 -15
- package/docs/ru/releases/v9.md +59 -1
- package/docs/ru/self_hosting.md +349 -0
- package/docs/tr/intlayer_CMS.md +16 -1
- package/docs/tr/releases/v9.md +46 -1
- package/docs/tr/self_hosting.md +349 -0
- package/docs/uk/intlayer_CMS.md +16 -1
- package/docs/uk/releases/v9.md +58 -1
- package/docs/uk/self_hosting.md +349 -0
- package/docs/vi/releases/v9.md +31 -1
- package/docs/vi/self_hosting.md +349 -0
- package/docs/zh/releases/v9.md +31 -1
- package/docs/zh/self_hosting.md +349 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +20 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-06-30
|
|
3
|
+
updatedAt: 2026-06-30
|
|
4
|
+
title: Intlayerのセルフホスティング
|
|
5
|
+
description: 単一のコマンドでIntlayerの完全なインスタンスを独自のインフラストラクチャ上で実行できます。Intlayer Cloudアカウントは不要です。
|
|
6
|
+
keywords:
|
|
7
|
+
- セルフホスティング
|
|
8
|
+
- Docker
|
|
9
|
+
- Docker Compose
|
|
10
|
+
- Intlayer
|
|
11
|
+
- CMS
|
|
12
|
+
- インストール
|
|
13
|
+
- インフラストラクチャ
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- self-hosting
|
|
17
|
+
author: aymericzip
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Intlayerのセルフホスティング
|
|
21
|
+
|
|
22
|
+
Intlayerは、Intlayer Cloudアカウントを必要とせず、独自のインフラストラクチャ上で完全に実行できます。単一のコマンドで、本番環境に対応したスタックを起動します。
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
インストーラーは `docker-compose.yml` と `.env` をダウンロードし、必要なシークレットを自動生成して、すべてのコンテナを `docker compose up -d` で起動します。
|
|
29
|
+
|
|
30
|
+
## 目次
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## アーキテクチャ
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
┌─────────────────────────────┐
|
|
40
|
+
browser ──────▶ │ app (TanStack Start) :3000│ ──┐
|
|
41
|
+
└─────────────────────────────┘ │ VITE_BACKEND_URL
|
|
42
|
+
┌─────────────────────────────┐ │
|
|
43
|
+
│ backend (Fastify/Bun) :3100│ ◀─┘
|
|
44
|
+
└──────────────┬──────────────┘
|
|
45
|
+
┌──────────┬─────────┼──────────┬───────────┐
|
|
46
|
+
▼ ▼ ▼ ▼ ▼
|
|
47
|
+
mongo:27017 redis:6379 minio:9000 mailpit:1025 Chromium
|
|
48
|
+
(1ノードRS) (S3 API) (SMTP) (インイメージ)
|
|
49
|
+
minio:9001 mailpit:8025
|
|
50
|
+
(コンソール) (ウェブUI)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Chromium (Puppeteerのスクリーンショット生成に使用) はバックエンドイメージ内にバンドルされており、別のコンテナは必要ありません。
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 前提条件
|
|
58
|
+
|
|
59
|
+
- **Docker** ≥ 24 および **Docker Compose** ≥ v2。いずれかが不足している場合、インストーラーはインストールリンクを表示して終了します。
|
|
60
|
+
- ホスト上でポート `3000`、`3100`、`8025`、`9000`、`9001` が利用可能であること。
|
|
61
|
+
- LinuxまたはmacOSホスト(またはWindows上のWSL2)。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## クイックスタート
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
インストーラーの動作:
|
|
72
|
+
|
|
73
|
+
1. `docker` と `docker compose` が存在するかどうかを確認します。
|
|
74
|
+
2. `docker-compose.yml` と `.env.example` を `./intlayer/` にダウンロードします。
|
|
75
|
+
3. `.env` が存在しない場合、例をコピーし、`BETTER_AUTH_SECRET`、`S3_ACCESS_KEY_ID`、`S3_SECRET_ACCESS_KEY` 用に `openssl rand` を介してランダムなシークレットを生成します。
|
|
76
|
+
4. `docker compose pull` + `docker compose up -d` を実行します。
|
|
77
|
+
5. URLを表示します: ダッシュボード `:3000`、API `:3100`、メールUI `:8025`、MinIOコンソール `:9001`。
|
|
78
|
+
|
|
79
|
+
スタックが起動したら、**http://localhost:3000** を開き、最初のIntlayerアカウントを作成してください。
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## サービス
|
|
84
|
+
|
|
85
|
+
| サービス | イメージ | ホストポート | 目的 |
|
|
86
|
+
| ----------- | ------------------------------------ | -------------------------------- | ------------------------------------------------------------ |
|
|
87
|
+
| **app** | `apps/app/Dockerfile` からビルド | `3000` | TanStack Start ダッシュボード (CMS UI) |
|
|
88
|
+
| **backend** | `apps/backend/Dockerfile` からビルド | `3100` | Fastify REST API (`/health` エンドポイント) |
|
|
89
|
+
| **mongo** | `mongo:7` | 内部 | シングルノードレプリカセット (`rs0`) |
|
|
90
|
+
| **redis** | `redis:7-alpine` | 内部 | ジョブキュー (BullMQ) とキャッシュ (ioredis) |
|
|
91
|
+
| **minio** | `minio/minio` | `9000` (S3), `9001` (コンソール) | アバターとスクリーンショット用のS3互換オブジェクトストレージ |
|
|
92
|
+
| **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (ウェブUI) | ローカルトランザクションメールシンク |
|
|
93
|
+
|
|
94
|
+
内部ポート (mongo, redis) は、デフォルトではホストに公開されません。
|
|
95
|
+
|
|
96
|
+
> MinIOポート `9000` は、アップロードされたアセット (アバター、スクリーンショット) が `S3_PUBLIC_URL=http://localhost:9000/intlayer` から直接読み込まれるため、ブラウザから到達可能である必要があります。
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 環境変数
|
|
101
|
+
|
|
102
|
+
インストーラーはすぐに使用できる `.env` を生成します。以下の表は、すべての変数について説明しています。
|
|
103
|
+
|
|
104
|
+
### 必須 (自動生成またはプロンプトによる入力)
|
|
105
|
+
|
|
106
|
+
| 変数 | 例 | 説明 |
|
|
107
|
+
| ---------------------- | ----------------------------------------------- | ----------------------------------------------------- |
|
|
108
|
+
| `NODE_ENV` | `production` | ランタイム環境 |
|
|
109
|
+
| `PORT` | `3100` | バックエンドのリスニングポート |
|
|
110
|
+
| `BACKEND_URL` | `http://localhost:3100` | バックエンドAPIの公開URL |
|
|
111
|
+
| `APP_URL` | `http://localhost:3000` | ダッシュボードの公開URL |
|
|
112
|
+
| `DOMAIN` | `localhost` | クッキードメイン |
|
|
113
|
+
| `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | MongoDBの完全な接続URI |
|
|
114
|
+
| `REDIS_URL` | `redis://redis:6379` | Redisの接続URL |
|
|
115
|
+
| `BETTER_AUTH_SECRET` | _(生成済み)_ | セッション署名用の32バイトのシークレット |
|
|
116
|
+
| `MAIL_PROVIDER` | `smtp` | メールトランスポート: `smtp` または `resend` |
|
|
117
|
+
| `MAIL_SMTP_HOST` | `mailpit` | SMTPホスト名 (Mailpitコンテナ名) |
|
|
118
|
+
| `MAIL_SMTP_PORT` | `1025` | SMTPポート |
|
|
119
|
+
| `MAIL_FROM` | `Intlayer <no-reply@localhost>` | 送信元アドレス |
|
|
120
|
+
| `S3_ENDPOINT` | `http://minio:9000` | S3互換エンドポイント |
|
|
121
|
+
| `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | ブラウザによるアセット読み込み用の公開URL |
|
|
122
|
+
| `S3_BUCKET_NAME` | `intlayer` | バケット名 |
|
|
123
|
+
| `S3_ACCESS_KEY_ID` | _(生成済み)_ | MinIOアクセスキー |
|
|
124
|
+
| `S3_SECRET_ACCESS_KEY` | _(生成済み)_ | MinIOシークレットキー |
|
|
125
|
+
| `VITE_BACKEND_URL` | `http://localhost:3100` | ビルド時にダッシュボードに組み込まれるバックエンドURL |
|
|
126
|
+
| `VITE_DOMAIN` | `localhost` | ビルド時にダッシュボードに組み込まれるドメイン |
|
|
127
|
+
|
|
128
|
+
### オプション (存在しない場合でも機能は正常に劣化します)
|
|
129
|
+
|
|
130
|
+
| 変数 | 機能 |
|
|
131
|
+
| -------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
132
|
+
| `OPENAI_API_KEY` | AIアシストによる翻訳とコンテンツ監査 |
|
|
133
|
+
| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | 請求とサブスクリプション管理 |
|
|
134
|
+
| `RESEND_API_KEY` | Resendを介したトランザクションメール (設定されている場合、Mailpitを上書き) |
|
|
135
|
+
| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuthログイン |
|
|
136
|
+
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuthログイン |
|
|
137
|
+
| `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | GitLab OAuthログイン |
|
|
138
|
+
| `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Microsoft OAuthログイン |
|
|
139
|
+
| `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | LinkedIn OAuthログイン |
|
|
140
|
+
| `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Atlassian OAuthログイン |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Intlayerプロジェクトの接続
|
|
145
|
+
|
|
146
|
+
スタックが稼働したら、`intlayer.org` の代わりに自己ホスト型のバックエンドとダッシュボードを指すようにプロジェクトを設定します。
|
|
147
|
+
|
|
148
|
+
### プロジェクト設定
|
|
149
|
+
|
|
150
|
+
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
151
|
+
import type { IntlayerConfig } from "intlayer";
|
|
152
|
+
|
|
153
|
+
const config: IntlayerConfig = {
|
|
154
|
+
editor: {
|
|
155
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
156
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 自己ホスト型CMSダッシュボードのURL。
|
|
160
|
+
* デフォルト: https://app.intlayer.org
|
|
161
|
+
*/
|
|
162
|
+
cmsURL: process.env.INTLAYER_CMS_URL, // 例: http://localhost:3000
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 自己ホスト型バックエンドAPIのURL。
|
|
166
|
+
* デフォルト: https://back.intlayer.org
|
|
167
|
+
*/
|
|
168
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // 例: http://localhost:3100
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export default config;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
プロジェクトの `.env` で環境変数を設定します。
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
INTLAYER_CMS_URL=http://localhost:3000
|
|
179
|
+
INTLAYER_BACKEND_URL=http://localhost:3100
|
|
180
|
+
INTLAYER_CLIENT_ID=<your-client-id>
|
|
181
|
+
INTLAYER_CLIENT_SECRET=<your-client-secret>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
自己ホスト型ダッシュボードの **Projects → Access keys** (`http://localhost:3000/projects`) でアクセス認証情報を作成します。
|
|
185
|
+
|
|
186
|
+
### `@intlayer/api` SDK
|
|
187
|
+
|
|
188
|
+
`@intlayer/api` SDKをプログラムで利用する場合は、`backendURL` を明示的に渡します。
|
|
189
|
+
|
|
190
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
191
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
192
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
193
|
+
|
|
194
|
+
const cms = createIntlayerCMS({
|
|
195
|
+
editor: {
|
|
196
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
197
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
198
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // http://localhost:3100
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## アップグレード
|
|
208
|
+
|
|
209
|
+
既存のデプロイメントでインストーラーを再実行すると、ローリングアップグレードが実行されます。
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
これにより、最新のイメージがプルされ、`docker compose pull && docker compose up -d` でコンテナが再起動されます。既存のボリューム (`mongo-data`、`redis-data`、`minio-data`) は保持され、データ損失はありません。
|
|
216
|
+
|
|
217
|
+
`./intlayer/` ディレクトリ内で手動でアップグレードするには:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
docker compose pull
|
|
221
|
+
docker compose up -d
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## バックアップと復元
|
|
227
|
+
|
|
228
|
+
すべての永続データは、3つの名前付きDockerボリュームに保存されます。
|
|
229
|
+
|
|
230
|
+
### バックアップ
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
docker run --rm \
|
|
234
|
+
-v intlayer_mongo-data:/data \
|
|
235
|
+
-v "$(pwd)":/backup \
|
|
236
|
+
busybox tar czf /backup/mongo-data.tar.gz /data
|
|
237
|
+
|
|
238
|
+
docker run --rm \
|
|
239
|
+
-v intlayer_redis-data:/data \
|
|
240
|
+
-v "$(pwd)":/backup \
|
|
241
|
+
busybox tar czf /backup/redis-data.tar.gz /data
|
|
242
|
+
|
|
243
|
+
docker run --rm \
|
|
244
|
+
-v intlayer_minio-data:/data \
|
|
245
|
+
-v "$(pwd)":/backup \
|
|
246
|
+
busybox tar czf /backup/minio-data.tar.gz /data
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 復元
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
docker run --rm \
|
|
253
|
+
-v intlayer_mongo-data:/data \
|
|
254
|
+
-v "$(pwd)":/backup \
|
|
255
|
+
busybox tar xzf /backup/mongo-data.tar.gz -C /
|
|
256
|
+
|
|
257
|
+
# redis-data と minio-data についても同様に繰り返します
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## リバースプロキシの使用 (Nginx / Caddy)
|
|
263
|
+
|
|
264
|
+
本番環境のデプロイでは、appコンテナとbackendコンテナを直接公開するのではなく、リバースプロキシをそれらの前に配置します。
|
|
265
|
+
|
|
266
|
+
### Nginxの例
|
|
267
|
+
|
|
268
|
+
```nginx
|
|
269
|
+
server {
|
|
270
|
+
listen 80;
|
|
271
|
+
server_name cms.example.com;
|
|
272
|
+
|
|
273
|
+
location / {
|
|
274
|
+
proxy_pass http://localhost:3000;
|
|
275
|
+
proxy_set_header Host $host;
|
|
276
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
server {
|
|
281
|
+
listen 80;
|
|
282
|
+
server_name api.example.com;
|
|
283
|
+
|
|
284
|
+
location / {
|
|
285
|
+
proxy_pass http://localhost:3100;
|
|
286
|
+
proxy_set_header Host $host;
|
|
287
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
公開ドメインに合わせて、以下の `.env` 変数を更新してください。
|
|
293
|
+
|
|
294
|
+
```sh
|
|
295
|
+
BACKEND_URL=https://api.example.com
|
|
296
|
+
APP_URL=https://cms.example.com
|
|
297
|
+
DOMAIN=example.com
|
|
298
|
+
VITE_BACKEND_URL=https://api.example.com
|
|
299
|
+
VITE_DOMAIN=example.com
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
> `VITE_*` 変数はビルド時にダッシュボードイメージに組み込まれます。イメージがビルドされた後に変更した場合、`app` イメージをリビルドするか (`docker compose build app`)、ランタイム設定インジェクションを使用する必要があります。
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## トラブルシューティング
|
|
307
|
+
|
|
308
|
+
### 最初の起動時にバックエンドがクラッシュループする
|
|
309
|
+
|
|
310
|
+
バックエンドが起動する前に、MongoDBとRedisが正常である必要があります。composeファイルは `condition: service_healthy` とともに `depends_on` を使用しています。バックエンドの再起動が繰り返される場合は、`mongo` と `redis` のヘルスチェックがパスしているか確認してください。
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
docker compose ps
|
|
314
|
+
docker compose logs mongo
|
|
315
|
+
docker compose logs redis
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### ダッシュボードがAPIに到達できない
|
|
319
|
+
|
|
320
|
+
`VITE_BACKEND_URL` が、バックエンドが**ブラウザ**から到達可能なURL (Dockerネットワークではなく) と一致していることを確認してください。バックエンドポートを変更したり、リバースプロキシを追加した場合は、ダッシュボードイメージをリビルドしてください。
|
|
321
|
+
|
|
322
|
+
```sh
|
|
323
|
+
docker compose build app
|
|
324
|
+
docker compose up -d app
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### メールが送信されない
|
|
328
|
+
|
|
329
|
+
デフォルトでは、すべての送信メールはMailpitによって捕捉されます。送信されたメッセージを確認するには、`http://localhost:8025` を開いてください。実際のメールを送信するには、`.env` で `MAIL_PROVIDER=resend` と `RESEND_API_KEY=<your-key>` を設定し、バックエンドを再起動します。
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
docker compose restart backend
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### MinIOバケットが見つからない
|
|
336
|
+
|
|
337
|
+
`minio-init` ワンショットサービスが実行されなかった場合 (またはMinIOが準備できる前に実行された場合) は、手動でバケットを作成してください。
|
|
338
|
+
|
|
339
|
+
```sh
|
|
340
|
+
docker compose run --rm minio-init
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 役立つリンク
|
|
346
|
+
|
|
347
|
+
- [Intlayer CMS ドキュメント](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_CMS.md)
|
|
348
|
+
- [設定リファレンス](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/configuration.md)
|
|
349
|
+
- [CMS SDK — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
|
package/docs/ko/intlayer_CMS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-29
|
|
4
4
|
title: Intlayer CMS | Intlayer CMS에 콘텐츠 외부화하기
|
|
5
5
|
description: 콘텐츠 관리를 팀에 위임하기 위해 Intlayer CMS에 콘텐츠를 외부화하세요.
|
|
6
6
|
keywords:
|
|
@@ -18,6 +18,12 @@ slugs:
|
|
|
18
18
|
- cms
|
|
19
19
|
youtubeVideo: https://www.youtube.com/watch?v=UDDTnirwi_4
|
|
20
20
|
history:
|
|
21
|
+
- version: 9.0.0
|
|
22
|
+
date: 2026-06-30
|
|
23
|
+
changes: "Self-Hosting 섹션 추가: Docker Compose 부트스트랩, 서비스 인벤토리, SDK 구성, 선택적 기능 및 업그레이드 참고 사항"
|
|
24
|
+
- version: 9.0.0
|
|
25
|
+
date: 2026-06-29
|
|
26
|
+
changes: "프로그래밍 방식 CMS 액세스를 위한 @intlayer/api SDK (createIntlayerCMS) 섹션 추가"
|
|
21
27
|
- version: 6.0.1
|
|
22
28
|
date: 2025-09-22
|
|
23
29
|
changes: "라이브 동기화 문서 추가"
|
|
@@ -241,6 +247,158 @@ bun x intlayer dictionary push -d my-first-dictionary-key --env production
|
|
|
241
247
|
|
|
242
248
|
그런 다음 [Intlayer CMS](https://app.intlayer.org/content)에서 사전을 보고 관리할 수 있습니다.
|
|
243
249
|
|
|
250
|
+
## `@intlayer/api` SDK를 사용한 프로그래밍 방식 액세스
|
|
251
|
+
|
|
252
|
+
CLI 및 시각적 편집기를 넘어, Intlayer는 [`@intlayer/api`](https://www.npmjs.com/package/@intlayer/api) 패키지에 타입이 지정된 SDK를 제공합니다. 이를 통해 CMS를 **헤드리스 콘텐츠 데이터베이스**로 취급할 수 있습니다. 프로젝트를 가져오고, 사전을 가져오며, 자신만의 애플리케이션, 스크립트 또는 CI 파이프라인에서 직접 푸시하거나 업데이트할 수 있습니다.
|
|
253
|
+
|
|
254
|
+
SDK는 인증을 자동으로 처리합니다. `clientId` 및 `clientSecret`이 (Intlayer 구성 또는 환경에서) 사용 가능한 한, OAuth2 액세스 토큰을 자동으로 획득하고 새로 고치며 모든 요청에 서명합니다.
|
|
255
|
+
|
|
256
|
+
### 설치
|
|
257
|
+
|
|
258
|
+
```bash packageManager="npm"
|
|
259
|
+
npm install @intlayer/api
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```bash packageManager="yarn"
|
|
263
|
+
yarn add @intlayer/api
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash packageManager="pnpm"
|
|
267
|
+
pnpm add @intlayer/api
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="bun"
|
|
271
|
+
bun add @intlayer/api
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### 작동 방식: 인증기 + 엔드포인트
|
|
275
|
+
|
|
276
|
+
SDK는 번들 크기를 작게 유지하기 위해 의도적으로 **두 개의 개별 임포트**로 분리되어 있습니다:
|
|
277
|
+
|
|
278
|
+
1. `createIntlayerCMS` — 경량 **인증기**를 생성합니다. 자격 증명과 관리되는 액세스 토큰만 포함하며, 특정 도메인에 대해서는 알지 못합니다.
|
|
279
|
+
2. `dictionaryEndpoint`, `projectEndpoint`, … — 도메인별 **엔드포인트 바인더**로, 각각 자체 하위 경로 (`@intlayer/api/dictionary`, `@intlayer/api/project`, …)에서 임포트됩니다. 필요한 엔드포인트에 인증기를 전달합니다.
|
|
280
|
+
|
|
281
|
+
각 엔드포인트가 개별적으로 임포트되므로, 번들에는 실제로 사용하는 도메인만 포함됩니다. `dictionaryEndpoint`를 임포트해도 프로젝트, AI 또는 다른 도메인 클라이언트가 함께 포함되지 않습니다.
|
|
282
|
+
|
|
283
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
284
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
285
|
+
|
|
286
|
+
// 구성은 선택 사항입니다: 생략하면, 자격 증명은
|
|
287
|
+
// INTLAYER_CLIENT_ID 및 INTLAYER_CLIENT_SECRET 환경 변수를 해석하는
|
|
288
|
+
// `@intlayer/config/built`에서 읽어옵니다.
|
|
289
|
+
export const cmsAuthenticator = createIntlayerCMS();
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
> [!WARNING]
|
|
293
|
+
> CMS 자격 증명 (`clientId` / `clientSecret`)은 콘텐츠에 대한 **쓰기 권한**을 부여합니다. 인증기는 **서버 측**에서만 생성해야 합니다 (서버 액션, 라우트 핸들러, 스크립트, CI). 클라이언트 측 코드에 임포트하거나 브라우저에 자격 증명을 노출하지 마십시오.
|
|
294
|
+
|
|
295
|
+
빌드 시간 구성에 의존하지 않으려면 자격 증명을 명시적으로 전달하세요:
|
|
296
|
+
|
|
297
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
298
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
299
|
+
|
|
300
|
+
export const cmsAuthenticator = createIntlayerCMS({
|
|
301
|
+
editor: {
|
|
302
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
303
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
304
|
+
// 선택 사항, 자체 호스팅 백엔드의 경우:
|
|
305
|
+
// backendURL: process.env.INTLAYER_BACKEND_URL,
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
> [Intlayer Dashboard - Projects](https://app.intlayer.org/projects)에서 새 액세스 키를 생성하여 자격 증명을 얻으세요.
|
|
311
|
+
|
|
312
|
+
### 프로젝트 가져오기
|
|
313
|
+
|
|
314
|
+
```typescript fileName="projects.ts" codeFormat="typescript"
|
|
315
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
316
|
+
import { projectEndpoint } from "@intlayer/api/project";
|
|
317
|
+
|
|
318
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
319
|
+
|
|
320
|
+
// 자격 증명으로 액세스 가능한 프로젝트 목록을 가져옵니다.
|
|
321
|
+
const { data: projects } =
|
|
322
|
+
await projectEndpoint(cmsAuthenticator).getProjects();
|
|
323
|
+
|
|
324
|
+
// 선택된 프로젝트의 통합된 현지화 인사이트를 읽습니다.
|
|
325
|
+
const { data: insights } =
|
|
326
|
+
await projectEndpoint(cmsAuthenticator).getProjectInsights();
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 사전 가져오기
|
|
330
|
+
|
|
331
|
+
```typescript fileName="read-dictionaries.ts" codeFormat="typescript"
|
|
332
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
333
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
334
|
+
|
|
335
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
336
|
+
|
|
337
|
+
// 프로젝트의 모든 원격 사전을 나열합니다.
|
|
338
|
+
const { data: dictionaries } =
|
|
339
|
+
await dictionaryEndpoint(cmsAuthenticator).getDictionaries();
|
|
340
|
+
|
|
341
|
+
// 또는 키로 단일 사전을 가져옵니다.
|
|
342
|
+
const { data: dictionary } = await dictionaryEndpoint(
|
|
343
|
+
cmsAuthenticator
|
|
344
|
+
).getDictionary("my-first-dictionary-key");
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### 사전 푸시 및 업데이트
|
|
348
|
+
|
|
349
|
+
CMS를 데이터베이스로 사용하여 콘텐츠를 다시 작성합니다:
|
|
350
|
+
|
|
351
|
+
```typescript fileName="write-dictionaries.ts" codeFormat="typescript"
|
|
352
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
353
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
354
|
+
|
|
355
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
356
|
+
|
|
357
|
+
// 새 사전을 생성합니다.
|
|
358
|
+
await dictionaryEndpoint(cmsAuthenticator).addDictionary({
|
|
359
|
+
key: "my-first-dictionary-key",
|
|
360
|
+
content: { title: "Hello world" },
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// 사전 배치(batch)를 Upsert 합니다 (한 번의 호출로 생성 또는 업데이트).
|
|
364
|
+
await dictionaryEndpoint(cmsAuthenticator).pushDictionaries([
|
|
365
|
+
{ key: "home", content: { title: "Home" } },
|
|
366
|
+
{ key: "about", content: { title: "About" } },
|
|
367
|
+
]);
|
|
368
|
+
|
|
369
|
+
// 기존 사전을 업데이트합니다.
|
|
370
|
+
await dictionaryEndpoint(cmsAuthenticator).updateDictionary({
|
|
371
|
+
id: "<dictionary-id>",
|
|
372
|
+
key: "home",
|
|
373
|
+
content: { title: "Updated title" },
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
> 팁: 바인딩된 엔드포인트를 재사용하여 반복을 피하세요:
|
|
378
|
+
>
|
|
379
|
+
> ```typescript codeFormat="typescript"
|
|
380
|
+
> const dictionary = dictionaryEndpoint(cmsAuthenticator);
|
|
381
|
+
> await dictionary.pushDictionaries([myDictionary]);
|
|
382
|
+
> const { data } = await dictionary.getDictionaries();
|
|
383
|
+
> ```
|
|
384
|
+
|
|
385
|
+
### 단일 메서드 추출
|
|
386
|
+
|
|
387
|
+
모든 엔드포인트 메서드는 이미 인증되어 있으며 독립적입니다 (자체 토큰 처리 기능을 가짐). 따라서 메서드를 추출하여 전달할 수 있습니다. 예를 들어 종속성으로 주입하는 경우입니다.
|
|
388
|
+
|
|
389
|
+
```typescript fileName="push.ts" codeFormat="typescript"
|
|
390
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
391
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
392
|
+
|
|
393
|
+
const dictionary = dictionaryEndpoint(createIntlayerCMS());
|
|
394
|
+
|
|
395
|
+
// 이미 인증됨 — 각 호출 시 토큰을 자동으로 새로 고칩니다.
|
|
396
|
+
export const pushDictionaries = dictionary.pushDictionaries;
|
|
397
|
+
|
|
398
|
+
// 사용 예시
|
|
399
|
+
await pushDictionaries([{ key: "home", content: { title: "Home" } }]);
|
|
400
|
+
```
|
|
401
|
+
|
|
244
402
|
## 라이브 동기화
|
|
245
403
|
|
|
246
404
|
라이브 동기화는 앱이 런타임에 CMS 콘텐츠 변경 사항을 반영할 수 있게 합니다. 재빌드나 재배포가 필요 없습니다. 활성화되면 업데이트가 라이브 동기화 서버로 스트리밍되어 애플리케이션이 읽는 사전을 갱신합니다.
|
|
@@ -271,7 +429,7 @@ const config: IntlayerConfig = {
|
|
|
271
429
|
/**
|
|
272
430
|
* 사전이 어떻게 가져오는지를 제어합니다:
|
|
273
431
|
*
|
|
274
|
-
* - "
|
|
432
|
+
* - "fetch": 사전은 Live Sync API를 사용하여 동적으로 가져옵니다.
|
|
275
433
|
* useIntlayer를 useDictionaryDynamic으로 대체합니다.
|
|
276
434
|
*
|
|
277
435
|
* 참고: 라이브 모드는 Live Sync API를 사용하여 사전을 가져옵니다. API 호출이
|
|
@@ -288,6 +446,19 @@ export default config;
|
|
|
288
446
|
|
|
289
447
|
애플리케이션을 감싸기 위해 Live Sync 서버를 시작하세요:
|
|
290
448
|
|
|
449
|
+
독립형 서버 사용 예시:
|
|
450
|
+
|
|
451
|
+
```json5 fileName="package.json"
|
|
452
|
+
{
|
|
453
|
+
"scripts": {
|
|
454
|
+
// ... 다른 스크립트들
|
|
455
|
+
"live:start": "npx intlayer live",
|
|
456
|
+
},
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
`--process` 인수를 사용하여 애플리케이션 서버를 병렬로 사용할 수도 있습니다.
|
|
461
|
+
|
|
291
462
|
Next.js 사용 예시:
|
|
292
463
|
|
|
293
464
|
```json5 fileName="package.json"
|
|
@@ -320,11 +491,11 @@ CMS로부터 변경 알림을 받기 위해, Live Sync 서버는 백엔드와 SS
|
|
|
320
491
|
|
|
321
492
|
플로우 차트 (CMS/백엔드 -> Live Sync 서버 -> 애플리케이션 서버 -> 프론트엔드):
|
|
322
493
|
|
|
323
|
-

|
|
324
495
|
|
|
325
496
|
작동 방식:
|
|
326
497
|
|
|
327
|
-

|
|
328
499
|
|
|
329
500
|
### 개발 워크플로우 (로컬)
|
|
330
501
|
|
|
@@ -356,7 +527,7 @@ const config: IntlayerConfig = {
|
|
|
356
527
|
importMode: "fetch",
|
|
357
528
|
},
|
|
358
529
|
build: {
|
|
359
|
-
optimize: true,
|
|
530
|
+
optimize: true, // 기본값: process.env.NODE_ENV === 'production'
|
|
360
531
|
},
|
|
361
532
|
};
|
|
362
533
|
|
|
@@ -373,6 +544,18 @@ export default config;
|
|
|
373
544
|
- `live` 플래그는 빌드 시 각 사전에 대해 평가됩니다. 빌드 시 원격 콘텐츠가 `live=true`로 표시되지 않았다면, 해당 사전에 대해 라이브 싱크를 활성화하려면 다시 빌드해야 합니다.
|
|
374
545
|
- 라이브 싱크 서버는 `.intlayer`에 쓸 수 있어야 합니다. 컨테이너 환경에서는 `/.intlayer`에 쓰기 권한이 있는지 확인하세요.
|
|
375
546
|
|
|
547
|
+
## 자체 호스팅
|
|
548
|
+
|
|
549
|
+
Intlayer는 자체 인프라에서 완전히 실행될 수 있습니다. 한 줄의 명령어로 Docker Compose를 사용하여 전체 스택(대시보드, API, 데이터베이스, 객체 스토리지 및 이메일)을 부트스트랩할 수 있습니다:
|
|
550
|
+
|
|
551
|
+
```sh
|
|
552
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
전체 설정 가이드, 환경 변수 참조, 업그레이드 지침 및 백업/복원 절차는 [자체 호스팅 가이드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/self_hosting.md)를 참조하세요.
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
376
559
|
## 디버그
|
|
377
560
|
|
|
378
561
|
CMS에서 문제가 발생하면 다음을 확인하세요:
|
|
@@ -386,4 +569,4 @@ CMS에서 문제가 발생하면 다음을 확인하세요:
|
|
|
386
569
|
|
|
387
570
|
- 프로젝트 구성이 Intlayer CMS에 푸시되었는지 확인하세요.
|
|
388
571
|
|
|
389
|
-
- 비주얼 에디터는 iframe을 사용하여 웹사이트를 표시합니다. 웹사이트의 콘텐츠 보안 정책(CSP)이 CMS URL을 `frame-ancestors`로 허용하는지 확인하세요(기본값은 'https://intlayer.org'). 에디터 콘솔에서 오류가 있는지 확인하세요.
|
|
572
|
+
- 비주얼 에디터는 iframe을 사용하여 웹사이트를 표시합니다. 웹사이트의 콘텐츠 보안 정책(CSP)이 CMS URL을 `frame-ancestors`로 허용하는지 확인하세요(기본값은 'https://app.intlayer.org'). 에디터 콘솔에서 오류가 있는지 확인하세요.
|
package/docs/ko/releases/v9.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-29
|
|
4
4
|
title: 새로운 Intlayer v9 - 무엇이 달라졌나요?
|
|
5
5
|
description: Intlayer v9의 새로운 기능을 알아보세요. 인기 있는 i18n 라이브러리를 위한 드롭인 호환성 패키지와 컬렉션(Collections), 베리언트(Variants) 지원을 소개합니다.
|
|
6
6
|
keywords:
|
|
@@ -299,6 +299,34 @@ npm install intlayer react-native-intlayer
|
|
|
299
299
|
|
|
300
300
|
---
|
|
301
301
|
|
|
302
|
+
## CMS SDK: Intlayer를 헤드리스 콘텐츠 데이터베이스로 사용하기
|
|
303
|
+
|
|
304
|
+
Intlayer v9는 CMS를 프로그래밍 방식으로 다루기 위한 깔끔하고 자동 인증되는 SDK를 `@intlayer/api`에 포함합니다. 프로젝트 가져오기, 사전 가져오기, 그리고 자체 서버·스크립트·CI에서의 푸시 또는 업데이트가 가능합니다. 인증(OAuth2 `client_credentials`)은 자동으로 처리되고 갱신됩니다.
|
|
305
|
+
|
|
306
|
+
SDK는 **두 개의 분리된 import**로 나뉘어, 실제로 사용하는 도메인만 번들에 포함됩니다:
|
|
307
|
+
|
|
308
|
+
1. `createIntlayerCMS` — 자격 증명과 관리되는 토큰을 보유하는 가벼운 **인증기**(도메인 클라이언트는 번들되지 않음).
|
|
309
|
+
2. `dictionaryEndpoint`, `projectEndpoint`, … — 도메인별 **엔드포인트 바인더**로, 각각 자체 서브패스에서 가져옵니다.
|
|
310
|
+
|
|
311
|
+
```ts fileName="cms.ts"
|
|
312
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
313
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
314
|
+
|
|
315
|
+
// 구성은 선택 사항입니다: 자격 증명은 INTLAYER_CLIENT_ID /
|
|
316
|
+
// INTLAYER_CLIENT_SECRET(`@intlayer/config/built`로 해석됨)로 폴백됩니다.
|
|
317
|
+
const cms = createIntlayerCMS();
|
|
318
|
+
|
|
319
|
+
// 읽기
|
|
320
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
321
|
+
|
|
322
|
+
// 쓰기 — CMS를 데이터베이스처럼 사용
|
|
323
|
+
await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
> 보안: CMS 자격 증명은 콘텐츠에 대한 쓰기 권한을 부여합니다. 인증기는 항상 **서버 측**에서만 생성하고, `clientId` / `clientSecret`을 브라우저로 절대 보내지 마세요.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
302
330
|
## v8에서의 마이그레이션 노트
|
|
303
331
|
|
|
304
332
|
v8에서 업그레이드하는 경우, v9에는 하위 호환성을 깨뜨리는 변경 사항(breaking changes)이 포함되어 있지 않습니다. 하지만 다음과 같은 주요 변경 사항이 있습니다:
|
|
@@ -314,3 +342,4 @@ v8에서 업그레이드하는 경우, v9에는 하위 호환성을 깨뜨리는
|
|
|
314
342
|
- [호환 어댑터 패키지 가이드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/compat/index.md)
|
|
315
343
|
- [동적 딕셔너리 - 컬렉션 및 베리언트](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/index.md)
|
|
316
344
|
- [설정 레퍼런스](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/configuration.md)
|
|
345
|
+
- [CMS SDK - @intlayer/api를 통한 프로그래밍 방식 접근](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/intlayer_CMS.md)
|