--- createdAt: 2026-06-30 updatedAt: 2026-06-30 title: Auto-hospedagem do Intlayer description: Execute uma instância completa do Intlayer na sua própria infraestrutura com um único comando. Nenhuma conta Intlayer Cloud é necessária. keywords: - Auto-hospedagem - Docker - Docker Compose - Intlayer - CMS - Instalação - Infraestrutura slugs: - doc - self-hosting author: aymericzip --- # Auto-hospedagem do Intlayer 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: ```sh curl -fsSL https://intlayer.org/install.sh | sh ``` 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`. ## Sumário --- ## Arquitetura ``` ┌─────────────────────────────┐ browser ──────▶ │ app (TanStack Start) :3000│ ──┐ └─────────────────────────────┘ │ VITE_BACKEND_URL ┌─────────────────────────────┐ │ │ backend (Fastify/Bun) :3100│ ◀─┘ └──────────────┬──────────────┘ ┌──────────┬─────────┼──────────┬───────────┐ ▼ ▼ ▼ ▼ ▼ mongo:27017 redis:6379 minio:9000 mailpit:1025 Chromium (1-node RS) (S3 API) (SMTP) (in-image) minio:9001 mailpit:8025 (console) (web UI) ``` O Chromium (usado para a geração de screenshots do Puppeteer) é empacotado dentro da imagem do backend — nenhum container separado é necessário. --- ## Pré-requisitos - **Docker** ≥ 24 e **Docker Compose** ≥ v2. Se algum deles estiver faltando, o instalador exibe o link de instalação e sai. - Portas `3000`, `3100`, `8025`, `9000` e `9001` disponíveis no host. - Um host Linux ou macOS (ou WSL2 no Windows). --- ## Início rápido ```sh curl -fsSL https://intlayer.org/install.sh | sh ``` O que o instalador faz: 1. Verifica se `docker` e `docker compose` estão presentes. 2. Baixa `docker-compose.yml` e `.env.example` para `./intlayer/`. 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`. 4. Executa `docker compose pull` + `docker compose up -d`. 5. Imprime as URLs: dashboard `:3000`, API `:3100`, UI de e-mail `:8025`, console MinIO `:9001`. Após a stack estar ativa, abra **http://localhost:3000** e crie sua primeira conta. --- ## Serviços | Serviço | Imagem | Porta(s) do Host | Finalidade | | ----------- | ------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- | | **app** | built from `apps/app/Dockerfile` | `3000` | Dashboard TanStack Start (UI do CMS) | | **backend** | built from `apps/backend/Dockerfile` | `3100` | API REST Fastify (endpoint `/health`) | | **mongo** | `mongo:7` | internal | Conjunto de réplicas de nó único (`rs0`) | | **redis** | `redis:7-alpine` | internal | Filas de trabalho (BullMQ) e cache (ioredis) | | **minio** | `minio/minio` | `9000` (S3), `9001` (console) | Armazenamento de objetos compatível com S3 para avatares e screenshots | | **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (web UI) | Sink local de e-mail transacional | As portas internas (mongo, redis) não são expostas ao host por padrão. > 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`. --- ## Variáveis de ambiente O instalador gera um arquivo `.env` pronto para uso. A tabela abaixo descreve cada variável. ### Obrigatórias (auto-geradas ou solicitadas) | Variável | Exemplo | Descrição | | ---------------------- | ----------------------------------------------- | ---------------------------------------------------------------- | | `NODE_ENV` | `production` | Ambiente de tempo de execução | | `PORT` | `3100` | Porta de escuta do backend | | `BACKEND_URL` | `http://localhost:3100` | URL pública da API do backend | | `APP_URL` | `http://localhost:3000` | URL pública do dashboard | | `DOMAIN` | `localhost` | Domínio do cookie | | `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | URI de conexão completa do MongoDB | | `REDIS_URL` | `redis://redis:6379` | URL de conexão do Redis | | `BETTER_AUTH_SECRET` | _(generated)_ | Segredo de 32 bytes para assinatura de sessão | | `MAIL_PROVIDER` | `smtp` | Transporte de e-mail: `smtp` ou `resend` | | `MAIL_SMTP_HOST` | `mailpit` | Nome de host SMTP (nome do container Mailpit) | | `MAIL_SMTP_PORT` | `1025` | Porta SMTP | | `MAIL_FROM` | `Intlayer ` | Endereço do remetente | | `S3_ENDPOINT` | `http://minio:9000` | Endpoint compatível com S3 | | `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | URL pública para carregamento de ativos no navegador | | `S3_BUCKET_NAME` | `intlayer` | Nome do bucket | | `S3_ACCESS_KEY_ID` | _(generated)_ | Chave de acesso do MinIO | | `S3_SECRET_ACCESS_KEY` | _(generated)_ | Chave secreta do MinIO | | `VITE_BACKEND_URL` | `http://localhost:3100` | URL do backend incorporada ao dashboard no momento da compilação | | `VITE_DOMAIN` | `localhost` | Domínio incorporado ao dashboard no momento da compilação | ### Opcionais (recursos são degradados graciosamente quando ausentes) | Variável | Recurso | | -------------------------------------------------------- | -------------------------------------------------------------------- | | `OPENAI_API_KEY` | Tradução assistida por IA e auditoria de conteúdo | | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Gerenciamento de faturamento e assinaturas | | `RESEND_API_KEY` | E-mail transacional via Resend (sobrescreve Mailpit quando definido) | | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | Login OAuth do GitHub | | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Login OAuth do Google | | `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | Login OAuth do GitLab | | `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Login OAuth da Microsoft | | `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | Login OAuth do LinkedIn | | `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Login OAuth da Atlassian | --- ## Conectando seu projeto Intlayer Uma vez que a stack esteja em execução, aponte seu projeto para o backend e dashboard auto-hospedados em vez de `intlayer.org`. ### Configuração do projeto ```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]} import type { IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { editor: { clientId: process.env.INTLAYER_CLIENT_ID, clientSecret: process.env.INTLAYER_CLIENT_SECRET, /** * URL do dashboard CMS auto-hospedado. * Padrão: https://app.intlayer.org */ cmsURL: process.env.INTLAYER_CMS_URL, // e.g. http://localhost:3000 /** * URL da API do backend auto-hospedado. * Padrão: https://back.intlayer.org */ backendURL: process.env.INTLAYER_BACKEND_URL, // e.g. http://localhost:3100 }, }; export default config; ``` Defina as variáveis de ambiente no arquivo `.env` do seu projeto: ```sh INTLAYER_CMS_URL=http://localhost:3000 INTLAYER_BACKEND_URL=http://localhost:3100 INTLAYER_CLIENT_ID= INTLAYER_CLIENT_SECRET= ``` Crie credenciais de acesso no seu dashboard auto-hospedado em **Projetos → Chaves de acesso** em `http://localhost:3000/projects`. ### SDK `@intlayer/api` Ao usar o SDK `@intlayer/api` programaticamente, passe `backendURL` explicitamente: ```typescript fileName="cms.ts" codeFormat="typescript" import { createIntlayerCMS } from "@intlayer/api"; import { dictionaryEndpoint } from "@intlayer/api/dictionary"; const cms = createIntlayerCMS({ editor: { clientId: process.env.INTLAYER_CLIENT_ID, clientSecret: process.env.INTLAYER_CLIENT_SECRET, backendURL: process.env.INTLAYER_BACKEND_URL, // http://localhost:3100 }, }); const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries(); ``` --- ## Atualizando Reexecutar o instalador em uma implantação existente realiza uma atualização contínua: ```sh curl -fsSL https://intlayer.org/install.sh | sh ``` 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. Para atualizar manualmente de dentro do diretório `./intlayer/`: ```sh docker compose pull docker compose up -d ``` --- ## Backup e restauração Todos os dados persistentes residem em três volumes Docker nomeados. ### Backup ```sh docker run --rm \ -v intlayer_mongo-data:/data \ -v "$(pwd)":/backup \ busybox tar czf /backup/mongo-data.tar.gz /data docker run --rm \ -v intlayer_redis-data:/data \ -v "$(pwd)":/backup \ busybox tar czf /backup/redis-data.tar.gz /data docker run --rm \ -v intlayer_minio-data:/data \ -v "$(pwd)":/backup \ busybox tar czf /backup/minio-data.tar.gz /data ``` ### Restauração ```sh docker run --rm \ -v intlayer_mongo-data:/data \ -v "$(pwd)":/backup \ busybox tar xzf /backup/mongo-data.tar.gz -C / # Repita para redis-data e minio-data ``` --- ## Usando um proxy reverso (Nginx / Caddy) 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. ### Exemplo de Nginx ```nginx server { listen 80; server_name cms.example.com; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } server { listen 80; server_name api.example.com; location / { proxy_pass http://localhost:3100; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` Atualize as seguintes variáveis `.env` para corresponder aos seus domínios públicos: ```sh BACKEND_URL=https://api.example.com APP_URL=https://cms.example.com DOMAIN=example.com VITE_BACKEND_URL=https://api.example.com VITE_DOMAIN=example.com ``` > 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. --- ## Solução de problemas ### Backend em loop de falha na primeira inicialização 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: ```sh docker compose ps docker compose logs mongo docker compose logs redis ``` ### Dashboard não consegue acessar a API 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: ```sh docker compose build app docker compose up -d app ``` ### E-mail não está sendo enviado 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=` no `.env`, então reinicie o backend: ```sh docker compose restart backend ``` ### Bucket MinIO ausente 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: ```sh docker compose run --rm minio-init ``` --- ## Links úteis - [Documentação do Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md) - [Referência de configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md) - [SDK do CMS — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)