@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: Auto-hospedagem do Intlayer
|
|
5
|
+
description: Execute uma instância completa do Intlayer na sua própria infraestrutura com um único comando. Nenhuma conta Intlayer Cloud é necessária.
|
|
6
|
+
keywords:
|
|
7
|
+
- Auto-hospedagem
|
|
8
|
+
- Docker
|
|
9
|
+
- Docker Compose
|
|
10
|
+
- Intlayer
|
|
11
|
+
- CMS
|
|
12
|
+
- Instalação
|
|
13
|
+
- Infraestrutura
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- self-hosting
|
|
17
|
+
author: aymericzip
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Auto-hospedagem do Intlayer
|
|
21
|
+
|
|
22
|
+
O Intlayer pode ser executado inteiramente na sua própria infraestrutura — nenhuma conta Intlayer Cloud é necessária. Um único comando inicializa uma stack pronta para produção:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
O instalador baixa um `docker-compose.yml` e um `.env`, gera automaticamente os segredos necessários e inicia todos os containers com `docker compose up -d`.
|
|
29
|
+
|
|
30
|
+
## Sumário
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Arquitetura
|
|
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-node RS) (S3 API) (SMTP) (in-image)
|
|
49
|
+
minio:9001 mailpit:8025
|
|
50
|
+
(console) (web UI)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
O Chromium (usado para a geração de screenshots do Puppeteer) é empacotado dentro da imagem do backend — nenhum container separado é necessário.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Pré-requisitos
|
|
58
|
+
|
|
59
|
+
- **Docker** ≥ 24 e **Docker Compose** ≥ v2. Se algum deles estiver faltando, o instalador exibe o link de instalação e sai.
|
|
60
|
+
- Portas `3000`, `3100`, `8025`, `9000` e `9001` disponíveis no host.
|
|
61
|
+
- Um host Linux ou macOS (ou WSL2 no Windows).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Início rápido
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
O que o instalador faz:
|
|
72
|
+
|
|
73
|
+
1. Verifica se `docker` e `docker compose` estão presentes.
|
|
74
|
+
2. Baixa `docker-compose.yml` e `.env.example` para `./intlayer/`.
|
|
75
|
+
3. Se nenhum `.env` existir, copia o exemplo e gera segredos aleatórios para `BETTER_AUTH_SECRET`, `S3_ACCESS_KEY_ID` e `S3_SECRET_ACCESS_KEY` via `openssl rand`.
|
|
76
|
+
4. Executa `docker compose pull` + `docker compose up -d`.
|
|
77
|
+
5. Imprime as URLs: dashboard `:3000`, API `:3100`, UI de e-mail `:8025`, console MinIO `:9001`.
|
|
78
|
+
|
|
79
|
+
Após a stack estar ativa, abra **http://localhost:3000** e crie sua primeira conta.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Serviços
|
|
84
|
+
|
|
85
|
+
| Serviço | Imagem | Porta(s) do Host | Finalidade |
|
|
86
|
+
| ----------- | ------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- |
|
|
87
|
+
| **app** | built from `apps/app/Dockerfile` | `3000` | Dashboard TanStack Start (UI do CMS) |
|
|
88
|
+
| **backend** | built from `apps/backend/Dockerfile` | `3100` | API REST Fastify (endpoint `/health`) |
|
|
89
|
+
| **mongo** | `mongo:7` | internal | Conjunto de réplicas de nó único (`rs0`) |
|
|
90
|
+
| **redis** | `redis:7-alpine` | internal | Filas de trabalho (BullMQ) e cache (ioredis) |
|
|
91
|
+
| **minio** | `minio/minio` | `9000` (S3), `9001` (console) | Armazenamento de objetos compatível com S3 para avatares e screenshots |
|
|
92
|
+
| **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (web UI) | Sink local de e-mail transacional |
|
|
93
|
+
|
|
94
|
+
As portas internas (mongo, redis) não são expostas ao host por padrão.
|
|
95
|
+
|
|
96
|
+
> A porta `9000` do MinIO deve ser acessível pelo navegador porque os ativos carregados (avatares, screenshots) são carregados diretamente de `S3_PUBLIC_URL=http://localhost:9000/intlayer`.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Variáveis de ambiente
|
|
101
|
+
|
|
102
|
+
O instalador gera um arquivo `.env` pronto para uso. A tabela abaixo descreve cada variável.
|
|
103
|
+
|
|
104
|
+
### Obrigatórias (auto-geradas ou solicitadas)
|
|
105
|
+
|
|
106
|
+
| Variável | Exemplo | Descrição |
|
|
107
|
+
| ---------------------- | ----------------------------------------------- | ---------------------------------------------------------------- |
|
|
108
|
+
| `NODE_ENV` | `production` | Ambiente de tempo de execução |
|
|
109
|
+
| `PORT` | `3100` | Porta de escuta do backend |
|
|
110
|
+
| `BACKEND_URL` | `http://localhost:3100` | URL pública da API do backend |
|
|
111
|
+
| `APP_URL` | `http://localhost:3000` | URL pública do dashboard |
|
|
112
|
+
| `DOMAIN` | `localhost` | Domínio do cookie |
|
|
113
|
+
| `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | URI de conexão completa do MongoDB |
|
|
114
|
+
| `REDIS_URL` | `redis://redis:6379` | URL de conexão do Redis |
|
|
115
|
+
| `BETTER_AUTH_SECRET` | _(generated)_ | Segredo de 32 bytes para assinatura de sessão |
|
|
116
|
+
| `MAIL_PROVIDER` | `smtp` | Transporte de e-mail: `smtp` ou `resend` |
|
|
117
|
+
| `MAIL_SMTP_HOST` | `mailpit` | Nome de host SMTP (nome do container Mailpit) |
|
|
118
|
+
| `MAIL_SMTP_PORT` | `1025` | Porta SMTP |
|
|
119
|
+
| `MAIL_FROM` | `Intlayer <no-reply@localhost>` | Endereço do remetente |
|
|
120
|
+
| `S3_ENDPOINT` | `http://minio:9000` | Endpoint compatível com S3 |
|
|
121
|
+
| `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | URL pública para carregamento de ativos no navegador |
|
|
122
|
+
| `S3_BUCKET_NAME` | `intlayer` | Nome do bucket |
|
|
123
|
+
| `S3_ACCESS_KEY_ID` | _(generated)_ | Chave de acesso do MinIO |
|
|
124
|
+
| `S3_SECRET_ACCESS_KEY` | _(generated)_ | Chave secreta do MinIO |
|
|
125
|
+
| `VITE_BACKEND_URL` | `http://localhost:3100` | URL do backend incorporada ao dashboard no momento da compilação |
|
|
126
|
+
| `VITE_DOMAIN` | `localhost` | Domínio incorporado ao dashboard no momento da compilação |
|
|
127
|
+
|
|
128
|
+
### Opcionais (recursos são degradados graciosamente quando ausentes)
|
|
129
|
+
|
|
130
|
+
| Variável | Recurso |
|
|
131
|
+
| -------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
132
|
+
| `OPENAI_API_KEY` | Tradução assistida por IA e auditoria de conteúdo |
|
|
133
|
+
| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Gerenciamento de faturamento e assinaturas |
|
|
134
|
+
| `RESEND_API_KEY` | E-mail transacional via Resend (sobrescreve Mailpit quando definido) |
|
|
135
|
+
| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | Login OAuth do GitHub |
|
|
136
|
+
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Login OAuth do Google |
|
|
137
|
+
| `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | Login OAuth do GitLab |
|
|
138
|
+
| `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Login OAuth da Microsoft |
|
|
139
|
+
| `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | Login OAuth do LinkedIn |
|
|
140
|
+
| `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Login OAuth da Atlassian |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Conectando seu projeto Intlayer
|
|
145
|
+
|
|
146
|
+
Uma vez que a stack esteja em execução, aponte seu projeto para o backend e dashboard auto-hospedados em vez de `intlayer.org`.
|
|
147
|
+
|
|
148
|
+
### Configuração do projeto
|
|
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
|
+
* URL do dashboard CMS auto-hospedado.
|
|
160
|
+
* Padrão: https://app.intlayer.org
|
|
161
|
+
*/
|
|
162
|
+
cmsURL: process.env.INTLAYER_CMS_URL, // e.g. http://localhost:3000
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* URL da API do backend auto-hospedado.
|
|
166
|
+
* Padrão: https://back.intlayer.org
|
|
167
|
+
*/
|
|
168
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // e.g. http://localhost:3100
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export default config;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Defina as variáveis de ambiente no arquivo `.env` do seu projeto:
|
|
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
|
+
Crie credenciais de acesso no seu dashboard auto-hospedado em **Projetos → Chaves de acesso** em `http://localhost:3000/projects`.
|
|
185
|
+
|
|
186
|
+
### SDK `@intlayer/api`
|
|
187
|
+
|
|
188
|
+
Ao usar o SDK `@intlayer/api` programaticamente, passe `backendURL` explicitamente:
|
|
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
|
+
## Atualizando
|
|
208
|
+
|
|
209
|
+
Reexecutar o instalador em uma implantação existente realiza uma atualização contínua:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Isso baixa as imagens mais recentes e reinicia os containers com `docker compose pull && docker compose up -d`. Os volumes existentes (`mongo-data`, `redis-data`, `minio-data`) são preservados — sem perda de dados.
|
|
216
|
+
|
|
217
|
+
Para atualizar manualmente de dentro do diretório `./intlayer/`:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
docker compose pull
|
|
221
|
+
docker compose up -d
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Backup e restauração
|
|
227
|
+
|
|
228
|
+
Todos os dados persistentes residem em três volumes Docker nomeados.
|
|
229
|
+
|
|
230
|
+
### Backup
|
|
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
|
+
### Restauração
|
|
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
|
+
# Repita para redis-data e minio-data
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Usando um proxy reverso (Nginx / Caddy)
|
|
263
|
+
|
|
264
|
+
Para implantações em produção, coloque um proxy reverso na frente dos containers do aplicativo e do backend, em vez de expô-los diretamente.
|
|
265
|
+
|
|
266
|
+
### Exemplo de 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
|
+
Atualize as seguintes variáveis `.env` para corresponder aos seus domínios públicos:
|
|
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
|
+
> As variáveis `VITE_*` são incorporadas à imagem do dashboard no momento da compilação. Se você as alterar após a imagem ser construída, precisará reconstruir a imagem do `app` (`docker compose build app`) ou usar a injeção de configuração em tempo de execução.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Solução de problemas
|
|
307
|
+
|
|
308
|
+
### Backend em loop de falha na primeira inicialização
|
|
309
|
+
|
|
310
|
+
MongoDB e Redis devem estar saudáveis antes que o backend possa iniciar. O arquivo compose usa `depends_on` com `condition: service_healthy`. Se você notar reinícios repetidos do backend, verifique se os healthchecks do `mongo` e `redis` estão passando:
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
docker compose ps
|
|
314
|
+
docker compose logs mongo
|
|
315
|
+
docker compose logs redis
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Dashboard não consegue acessar a API
|
|
319
|
+
|
|
320
|
+
Verifique se `VITE_BACKEND_URL` corresponde à URL onde o backend é acessível a partir do **navegador** (não da rede Docker). Se você alterou a porta do backend ou adicionou um proxy reverso, reconstrua a imagem do dashboard:
|
|
321
|
+
|
|
322
|
+
```sh
|
|
323
|
+
docker compose build app
|
|
324
|
+
docker compose up -d app
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### E-mail não está sendo enviado
|
|
328
|
+
|
|
329
|
+
Por padrão, todos os e-mails de saída são capturados pelo Mailpit. Abra `http://localhost:8025` para ver as mensagens enviadas. Para enviar e-mails reais, defina `MAIL_PROVIDER=resend` e `RESEND_API_KEY=<sua-chave>` no `.env`, então reinicie o backend:
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
docker compose restart backend
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Bucket MinIO ausente
|
|
336
|
+
|
|
337
|
+
Se o serviço `minio-init` de execução única não foi executado (ou executou antes que o MinIO estivesse pronto), crie o bucket manualmente:
|
|
338
|
+
|
|
339
|
+
```sh
|
|
340
|
+
docker compose run --rm minio-init
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Links úteis
|
|
346
|
+
|
|
347
|
+
- [Documentação do Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md)
|
|
348
|
+
- [Referência de configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md)
|
|
349
|
+
- [SDK do CMS — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
|
package/docs/ru/intlayer_CMS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-30
|
|
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: "Добавлен раздел «Самостоятельное размещение»: начальная загрузка Docker Compose, инвентаризация сервисов, конфигурация SDK, необязательные функции и примечания по обновлению"
|
|
24
|
+
- version: 9.0.0
|
|
25
|
+
date: 2026-06-29
|
|
26
|
+
changes: "Добавлен раздел SDK @intlayer/api (createIntlayerCMS) для программного доступа к CMS"
|
|
21
27
|
- version: 6.0.1
|
|
22
28
|
date: 2025-09-22
|
|
23
29
|
changes: "Добавлена документация по live sync"
|
|
@@ -241,12 +247,162 @@ 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
|
+
## Программный доступ с помощью SDK `@intlayer/api`
|
|
251
|
+
|
|
252
|
+
Помимо CLI и визуального редактора, Intlayer поставляется с типизированным SDK в пакете [`@intlayer/api`](https://www.npmjs.com/package/@intlayer/api). Он позволяет вам рассматривать 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` никогда не подтягивает проект, ИИ или любой другой клиент домена.
|
|
282
|
+
|
|
283
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
284
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
285
|
+
|
|
286
|
+
// Конфигурация необязательна: если она пропущена, учётные данные считываются из
|
|
287
|
+
// `@intlayer/config/built`, который разрешает переменные окружения INTLAYER_CLIENT_ID и
|
|
288
|
+
// INTLAYER_CLIENT_SECRET.
|
|
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 - Проекты](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
|
+
// Обновить или вставить партию словарей (создать или обновить их за один вызов)
|
|
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 в режиме реального времени. Пересборка или повторный деплой не требуются. Когда функция включена, обновления передаются на сервер живой синхронизации, который обновляет словари, используемые вашим приложением.
|
|
247
405
|
|
|
248
|
-
> Живая синхронизация требует постоянного подключения к серверу и доступна в тарифном плане enterprise.
|
|
249
|
-
|
|
250
406
|
Включите живую синхронизацию, обновив конфигурацию Intlayer:
|
|
251
407
|
|
|
252
408
|
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
@@ -271,13 +427,13 @@ const config: IntlayerConfig = {
|
|
|
271
427
|
/**
|
|
272
428
|
* Управляет способом импорта словарей:
|
|
273
429
|
*
|
|
274
|
-
* - "
|
|
430
|
+
* - "fetch": словари загружаются динамически с использованием Live Sync API.
|
|
275
431
|
* Заменяет useIntlayer на useDictionaryDynamic.
|
|
276
432
|
*
|
|
277
|
-
* Примечание: Режим
|
|
278
|
-
* не удаётся, словари
|
|
279
|
-
* Примечание:
|
|
280
|
-
*
|
|
433
|
+
* Примечание: Режим "fetch" использует Live Sync API для загрузки словарей. Если вызов API
|
|
434
|
+
* не удаётся, словари импортируются динамически.
|
|
435
|
+
* Примечание: Только словари с удалённым содержимым и флагом "live" используют режим "fetch".
|
|
436
|
+
* Остальные используют динамический режим для повышения производительности.
|
|
281
437
|
*/
|
|
282
438
|
importMode: "fetch",
|
|
283
439
|
},
|
|
@@ -288,6 +444,19 @@ export default config;
|
|
|
288
444
|
|
|
289
445
|
Запустите сервер Live Sync, чтобы обернуть ваше приложение:
|
|
290
446
|
|
|
447
|
+
Пример использования автономного сервера:
|
|
448
|
+
|
|
449
|
+
```json5 fileName="package.json"
|
|
450
|
+
{
|
|
451
|
+
"scripts": {
|
|
452
|
+
// ... other scripts
|
|
453
|
+
"live:start": "npx intlayer live",
|
|
454
|
+
},
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Вы также можете использовать сервер вашего приложения параллельно, используя аргумент `--process`.
|
|
459
|
+
|
|
291
460
|
Пример с использованием Next.js:
|
|
292
461
|
|
|
293
462
|
```json5 fileName="package.json"
|
|
@@ -320,11 +489,11 @@ export default config;
|
|
|
320
489
|
|
|
321
490
|
Блок-схема (CMS/Backend -> Live Sync Server -> Application Server -> Frontend):
|
|
322
491
|
|
|
323
|
-

|
|
324
493
|
|
|
325
494
|
Как это работает:
|
|
326
495
|
|
|
327
|
-

|
|
328
497
|
|
|
329
498
|
### Рабочий процесс разработки (локально)
|
|
330
499
|
|
|
@@ -356,7 +525,7 @@ const config: IntlayerConfig = {
|
|
|
356
525
|
importMode: "fetch",
|
|
357
526
|
},
|
|
358
527
|
build: {
|
|
359
|
-
optimize: true,
|
|
528
|
+
optimize: true, // default: process.env.NODE_ENV === 'production'
|
|
360
529
|
},
|
|
361
530
|
};
|
|
362
531
|
|
|
@@ -370,9 +539,21 @@ export default config;
|
|
|
370
539
|
- Добавьте источник live sync в политику безопасности вашего сайта (CSP). Убедитесь, что URL live sync разрешён в `connect-src` (и в `frame-ancestors`, если это актуально).
|
|
371
540
|
- Live Sync не работает со статическим выводом. Для Next.js страница должна быть динамической, чтобы получать обновления во время выполнения (например, используйте `generateStaticParams`, `generateMetadata`, `getServerSideProps` или `getStaticProps` соответствующим образом, чтобы избежать ограничений полностью статического вывода).
|
|
372
541
|
- В CMS у каждого словаря есть флаг `live`. Только словари с `live=true` загружаются через API live sync; остальные импортируются динамически и остаются неизменными во время выполнения.
|
|
373
|
-
- Флаг `live` оценивается для каждого словаря во время
|
|
542
|
+
- Флаг `live` оценивается для каждого словаря во время сборки. Если удалённый контент не был помечен как `live=true` во время сборки, необходимо выполнить повторную сборку, чтобы включить Live Sync для этого словаря.
|
|
374
543
|
- Сервер live sync должен иметь возможность записывать в `.intlayer`. В контейнерах убедитесь, что есть права на запись в `/.intlayer`.
|
|
375
544
|
|
|
545
|
+
## Самостоятельное размещение (Self-Hosting)
|
|
546
|
+
|
|
547
|
+
Intlayer может работать полностью на вашей собственной инфраструктуре. Одна команда поднимает весь стек (дашборд, API, база данных, хранилище объектов и электронная почта) с помощью Docker Compose:
|
|
548
|
+
|
|
549
|
+
```sh
|
|
550
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Полное руководство по настройке, справочник по переменным окружения, инструкции по обновлению и процедуры резервного копирования/восстановления см. в [Руководстве по самостоятельному размещению](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/self_hosting.md).
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
376
557
|
## Отладка
|
|
377
558
|
|
|
378
559
|
Если вы столкнулись с проблемами в CMS, проверьте следующее:
|
|
@@ -381,9 +562,9 @@ export default config;
|
|
|
381
562
|
|
|
382
563
|
- Конфигурация [`editor`](https://intlayer.org/doc/concept/configuration#editor-configuration) корректно настроена в вашем конфигурационном файле Intlayer.
|
|
383
564
|
- Обязательные поля:
|
|
384
|
-
- URL приложения должен совпадать с тем, который вы указали в конфигурации редактора (`applicationURL`).
|
|
385
|
-
- URL CMS
|
|
565
|
+
- URL приложения должен совпадать с тем, который вы указали в конфигурации редактора (`applicationURL`).
|
|
566
|
+
- URL CMS
|
|
386
567
|
|
|
387
568
|
- Убедитесь, что конфигурация проекта была отправлена в Intlayer CMS.
|
|
388
569
|
|
|
389
|
-
- Визуальный редактор использует iframe для отображения вашего сайта. Убедитесь, что политика безопасности контента (CSP) вашего сайта разрешает URL CMS в качестве `frame-ancestors` (по умолчанию 'https://intlayer.org'). Проверьте консоль редактора на наличие ошибок.
|
|
570
|
+
- Визуальный редактор использует iframe для отображения вашего сайта. Убедитесь, что политика безопасности контента (CSP) вашего сайта разрешает URL CMS в качестве `frame-ancestors` (по умолчанию 'https://app.intlayer.org'). Проверьте консоль редактора на наличие ошибок.
|