# Instalação

> Instale o Nodaro self-hosted passo a passo: clone o repositório, configure .env, segredos, migrações e armazenamento, inicie, faça login e proteja a stack.

Source: https://nodaro.ai/pt-BR/docs/self-hosting/install

Este guia **instala** a Community Edition passo a passo, com os motivos por trás de cada etapa. É o mesmo fluxo do [Início rápido](https://nodaro.ai/docs/self-hosting/quickstart), mais serviços gerenciados, segredos, armazenamento e proteção da instalação. Na stack do Compose incluída, a maioria das etapas não exige nenhuma ação: leia-as para saber o que acontece e o que mudar depois.

## 1. Clonar e configurar
```bash
git clone https://github.com/nodaroai/app.nodaro.ai.git nodaro
cd nodaro
```

Na stack do Compose da Community Edition, o `.env` é opcional. O arquivo do Compose inclui o Supabase, o MinIO e o Redis com padrões que funcionam. Crie um `.env` só para adicionar chaves de provedor, mudar a URL pública ou apontar o Nodaro para os seus próprios serviços gerenciados.

Para criar um, copie o exemplo feito para a stack do Compose:

```bash
cp .env.community.example .env
```

**Não copie o .env.example para a stack do Compose:** 
O `.env.example` é a referência para instalações fora da stack do Compose. Os valores de exemplo dele, como `SUPABASE_URL=https://YOUR-PROJECT.supabase.co`, substituem os padrões do Compose e quebram o banco de dados incluído.

Os valores que você provavelmente vai definir:

```bash
PUBLIC_URL=http://localhost:3000        # your install's public address

# Only with a managed Supabase project instead of the bundled one:
SUPABASE_URL=https://YOUR-PROJECT.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...
SUPABASE_ANON_KEY=eyJ...

# At least one model provider:
KIE_API_KEY=
REPLICATE_API_TOKEN=
ANTHROPIC_API_KEY=
ELEVENLABS_API_KEY=
```

O arquivo do Compose passa uma lista fixa de variáveis para o app. Uma variável que não está nessa lista precisa ser adicionada ao serviço `nodaro` no `docker-compose.community.yml`. A página [Configuração](https://nodaro.ai/docs/self-hosting/configuration) lista todas as variáveis e diz quais delas o `.env` pode definir.

## 2. Gerar os segredos internos
O Nodaro usa dois segredos próprios:

| Variável | O que faz |
| --- | --- |
| `INTERNAL_ORCHESTRATOR_SECRET` | Autentica o orquestrador na API dentro de um contêiner do Nodaro. Pelo menos 32 caracteres. |
| `NODARO_ENCRYPTION_KEY` | Uma chave hexadecimal de 64 caracteres que criptografa as credenciais armazenadas: as chaves de provedor coladas em `/setup`, os tokens de login das redes sociais e as credenciais HTTP que os usuários salvam para o nó [**Saída de webhook** (Webhook Output)](https://nodaro.ai/docs/nodes/publish/webhook-output). `SOCIAL_ENCRYPTION_KEY` é o nome antigo e ainda funciona. |

**Na stack do Compose incluída, pule esta etapa.** O contêiner gera os dois na inicialização. Ele salva a chave de criptografia no volume `app-data`, em `/data/nodaro/encryption-key`, e a reutiliza em todas as inicializações seguintes. Faça backup desse volume junto com o banco de dados.

**Na sua própria orquestração**, como uma plataforma de hospedagem ou contêineres separados, defina os dois você mesmo:

```bash
echo "INTERNAL_ORCHESTRATOR_SECRET=$(openssl rand -hex 32)" >> .env
echo "NODARO_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
```

Guarde a `NODARO_ENCRYPTION_KEY` em segurança e nunca a altere: tudo o que ela criptografou fica ilegível com outra chave.

## 3. Aplicar as migrações do banco de dados
**Na stack incluída, isso é automático.** Na inicialização, o app aplica os arquivos de `supabase/migrations/` antes de a API iniciar. Ele lembra quais arquivos já aplicou e os pula na inicialização seguinte. Ele se recusa a iniciar com um banco de dados migrado pela metade, e o log dele indica o arquivo que falhou.

**Com um projeto gerenciado no Supabase**, defina `RUN_MIGRATIONS_ON_BOOT=false` e aplique as migrações você mesmo. Veja [Banco de dados](https://nodaro.ai/docs/self-hosting/database#apply-the-migrations-to-a-managed-project).

## 4. Configurar o armazenamento de objetos
### O MinIO incluído
Não há nada para configurar. O arquivo do Compose traz o MinIO com estes padrões:

| Variável | Padrão |
| --- | --- |
| `R2_ENDPOINT` | `http://minio:9000` |
| `R2_FORCE_PATH_STYLE` | `true` |
| `R2_BUCKET_NAME` | `nodaro-assets` |
| `R2_PUBLIC_URL` | `http://localhost:3000/storage/nodaro-assets` |

O servidor web do app serve a mídia em `/storage/`, então o navegador e o backend leem a mesma URL. O bucket é criado na primeira inicialização, com acesso público de leitura. A mídia fica no volume `minio-data`.

Quando servir a instalação em um domínio real, defina `R2_PUBLIC_URL=https://<your-domain>/storage/nodaro-assets`. Mude as credenciais do MinIO, `R2_ACCESS_KEY_ID` e `R2_SECRET_ACCESS_KEY`, antes de expor a stack.

### Cloudflare R2
O Cloudflare R2 é o recomendado para implantações reais, porque não cobra taxas de saída de dados.

1. Crie um bucket, por exemplo `nodaro-assets`, e defina `R2_BUCKET_NAME` com o nome dele.
2. Na aba **Settings** do bucket, ative o endereço público `r2.dev` ou associe um domínio personalizado. Copie essa URL para `R2_PUBLIC_URL`.
3. Em **Manage R2 API tokens**, crie um token com a permissão **Object Read & Write** neste bucket. Copie os valores dele para `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY` e `R2_ACCOUNT_ID`.
4. Na stack do Compose, defina também o endpoint e o estilo de endereçamento:

```bash
R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
R2_FORCE_PATH_STYLE=false
```

Um valor vazio não limpa essas duas variáveis: para uma variável vazia, o arquivo do Compose volta aos padrões do MinIO. Fora da stack do Compose, deixe as duas sem definir, e o endpoint é derivado de `R2_ACCOUNT_ID`.

Na inicialização, o log mostra uma linha `[storage] failed to create bucket`, que é inofensiva. Os tokens do R2 não podem criar buckets, e o seu já existe.

### Outros armazenamentos compatíveis com S3
Para AWS S3, Backblaze B2, DigitalOcean Spaces, Supabase Storage ou o seu próprio MinIO:

- Defina `R2_ENDPOINT` como a URL da API S3 do armazenamento.
- Defina `R2_FORCE_PATH_STYLE=true` para a maioria dos servidores self-hosted.
- Defina `R2_PUBLIC_URL` como a URL pública do bucket.
- Defina `R2_REGION` como a região do armazenamento, a menos que ele seja o Cloudflare R2 ou o MinIO.

O padrão de `R2_REGION` é `auto`, o valor próprio do Cloudflare R2, que o MinIO ignora. A AWS, o DigitalOcean Spaces (`nyc3`, `fra1` e outros) e um Supabase local (`local`) rejeitam `auto`. Nesse caso, toda requisição falha com um erro de autorização ou de endpoint que não menciona a região.

### Tornar a mídia legível publicamente
Há duas formas, e a maioria das instalações só precisa da primeira:

1. **Uma política de bucket.** É o padrão. Com um `R2_ENDPOINT` personalizado, o app cria o bucket na inicialização e dá a ele uma política de leitura anônima. O Cloudflare R2 não precisa dela: a configuração de bucket público dele já cobre isso.
2. **Uma ACL por objeto, com `STORAGE_OBJECT_ACL`.** Para armazenamentos que recusam uma política de bucket. O DigitalOcean Spaces é o caso comum: ele recusa uma política de bucket vinda de uma chave restrita a um único bucket. Defina `STORAGE_OBJECT_ACL=public-read`, e todo objeto que o app grava leva essa ACL.

Deixe `STORAGE_OBJECT_ACL` vazia, a menos que precise da segunda forma. Quando ela está vazia, nenhum cabeçalho de ACL é enviado. Quando ela está definida em um armazenamento cujas chaves não têm permissão para definir ACLs, todo upload falha. O Nodaro aceita as ACLs pré-configuradas padrão — `private`, `public-read`, `public-read-write`, `authenticated-read`, `aws-exec-read`, `bucket-owner-read` e `bucket-owner-full-control` — e recusa qualquer outro valor na inicialização.

## 5. Iniciar a stack
```bash
docker compose -f docker-compose.community.yml up
```

A imagem do app, `ghcr.io/nodaroai/nodaro-community`, é baixada pré-compilada. A primeira inicialização baixa cerca de 2,4 GB, em vez de compilar por 5 a 10 minutos, e as inicializações seguintes levam segundos. Os logs do Redis e do serviço `nodaro` aparecem lado a lado. Quando você vir esta linha, a API está no ar:

```text
nodaro-1  | server listening on http://0.0.0.0:9000
```

O servidor web, no mesmo contêiner, a disponibiliza na porta `3000`. Abra `http://localhost:3000`.

A tag `latest` acompanha a branch `main`. Para fixar uma versão e ter uma instalação reproduzível, defina `NODARO_IMAGE` no `.env`, por exemplo `NODARO_IMAGE=ghcr.io/nodaroai/nodaro-community:v1.23.0`. A página [Atualização](https://nodaro.ai/docs/self-hosting/updating) lista todas as tags.

Para, em vez disso, compilar a imagem a partir do código-fonte, rode `docker compose -f docker-compose.community.yml build`. Você só precisa disso quando altera o código. A URL pública, a porta, o domínio e as chaves do Supabase são lidos quando o contêiner inicia, então a imagem publicada passa a usá-los depois de uma reinicialização.

## 6. Fazer login pela primeira vez
Crie uma conta no app com um endereço de e-mail e uma senha. O serviço de login cria o usuário, e o Nodaro cria o perfil do usuário automaticamente. Na stack incluída, nenhum e-mail de confirmação é enviado.

Os usuários da Community Edition não têm restrições: não há registro de créditos nem painel de administração. Na Business edition, promova o seu primeiro administrador em seguida: veja [Primeiro usuário e administrador](https://nodaro.ai/docs/self-hosting/first-admin).

## Proteger a instalação antes de expô-la
Os padrões do Compose foram feitos para uso local e são públicos por definição. Antes que outras pessoas possam acessar a instalação:

### Gerar novas chaves de autenticação
```bash
node tools/generate-selfhost-keys.mjs >> .env
```

O script imprime `SUPABASE_JWT_SECRET`, `SUPABASE_ANON_KEY` e `SUPABASE_SERVICE_ROLE_KEY`. As duas chaves são assinadas com o segredo, então os três valores precisam vir da mesma execução. Uma chave anon alterada não exige recompilar a imagem: o contêiner a entrega ao navegador em tempo de execução, em `/config.js`.

### Definir novas senhas
Defina `POSTGRES_PASSWORD` e uma `DATABASE_URL` correspondente:

```bash
POSTGRES_PASSWORD=<new-password>
DATABASE_URL=postgres://postgres:<new-password>@db:5432/postgres
```

Defina também novas credenciais do MinIO em `R2_ACCESS_KEY_ID` e `R2_SECRET_ACCESS_KEY`.

O banco de dados alinha as senhas das roles internas com `POSTGRES_PASSWORD` só na primeira inicialização dele. Se o volume `db-data` já existir, apague o volume, o que apaga os seus dados, ou altere as senhas das roles manualmente como `supabase_admin`.

### Servir por HTTPS
Defina `PUBLIC_URL` como o seu endereço `https://` real e coloque um proxy reverso na frente da stack. Veja [Proxy reverso e HTTPS](https://nodaro.ai/docs/self-hosting/reverse-proxy).

### Decidir quem pode criar uma conta
A Community Edition foi feita para um único operador. Qualquer pessoa que consiga acessar a página de cadastro pode criar uma conta, e todo usuário logado pode alterar as chaves de provedor. Na Business edition, só os administradores gerenciam as chaves de provedor. Veja [Edições e perfis de superfície](https://nodaro.ai/docs/self-hosting/editions-and-profiles).

Aplique cada alteração com `docker compose -f docker-compose.community.yml up -d` e depois verifique `/setup`.

## Frequently asked questions

### De qual arquivo .env devo partir na stack do Compose?

Copie o .env.community.example para .env. Ele lista só o que a stack do Compose usa. O .env.example, maior, é uma referência para instalações fora da stack do Compose, e os valores de exemplo do Supabase que ele traz substituiriam os padrões que funcionam.

### Preciso gerar o INTERNAL_ORCHESTRATOR_SECRET e a NODARO_ENCRYPTION_KEY?

Não na stack do Compose incluída, que gera os dois na inicialização e guarda a chave de criptografia no volume app-data. Na sua própria orquestração, defina os dois como 32 bytes aleatórios em hexadecimal, por exemplo com openssl rand -hex 32.

### Como uso o Cloudflare R2 em vez do MinIO incluído?

Defina R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME e R2_PUBLIC_URL. Na stack do Compose, defina também R2_ENDPOINT como o endpoint r2.cloudflarestorage.com da sua conta e R2_FORCE_PATH_STYLE=false, porque valores vazios voltam aos padrões do MinIO.

### Como sei se a instalação iniciou corretamente?

Espere a linha de log server listening on http://0.0.0.0:9000 e abra http://localhost:3000/setup. Todos os cartões devem estar verdes, exceto o das chaves de provedor, até você adicionar uma.

### O que preciso mudar antes de expor a instalação a uma rede?

Gere novas chaves de autenticação com node tools/generate-selfhost-keys.mjs, defina uma nova POSTGRES_PASSWORD com uma DATABASE_URL correspondente e novas credenciais do MinIO, defina a PUBLIC_URL como o seu endereço https e coloque um proxy reverso na frente.
