Saltar para o conteúdo principal

Guia de Auto-Alojamento

:::warning Versão antiga em Rails Esta página documenta a versão antiga em Rails do Campbooks. É instável, já não é mantida e deixou de receber correções. O Campbooks está a ser reconstruído de raiz em Rust: para instalações novas, vê Auto-alojamento. :::

Execute a sua própria instância do Campbooks com Docker em poucos minutos. Este guia cobre a configuração completa: a pilha, os segredos necessários e como configurar cada integração externa.

Só quer experimentar localmente? Vá diretamente para Início rápido. A executá-lo num servidor a sério? Leia também Executar em produção.

O que obtém​

docker compose up executa três contentores:

ServiçoO que é
postgresPostgreSQL com a extensão pgvector (obrigatória)
webA aplicação Rails (Puma atrás do Thruster)
workerTarefas em segundo plano — digitalização de email, IA, indexação (Solid Queue)

O Postgres contém tudo: dados da aplicação, cache, tarefas e Action Cable (via os adaptadores Solid), mais embeddings vetoriais para pesquisa semântica (pgvector). Um quarto serviço, opensearch, é opcional e apenas suporta o autocompletar de texto completo de contactos — consulte Pesquisa.

Os ficheiros carregados (anexos de email guardados como Documentos) ficam num volume Docker local por omissão, ou em armazenamento de objetos compatível com S3, se configurado.

Pré-requisitos​

  • Docker e o plugin Docker Compose (Docker Desktop, ou Docker Engine ≥ 24 com docker compose)
  • Cerca de 2 GB de RAM livres para a pilha padrão (adicione ~1 GB se ativar o OpenSearch)
  • openssl na sua máquina (já presente no macOS/Linux) para gerar segredos
  • Opcional, para uma implementação real: um nome de domínio e um proxy reverso com terminação TLS (Caddy, Traefik, nginx)

Início rápido​

git clone https://github.com/notacamp/campbooks.git
cd campbooks

cp .env.example .env
bin/generate-secrets # preenche SECRET_KEY_BASE, as chaves de encriptação AR e a palavra-passe da BD

# (opcional) edite .env para adicionar uma chave de IA e as integrações que pretende
docker compose up -d --build

# acompanhe o arranque; o primeiro boot cria as bases de dados e executa as migrações
docker compose logs -f web

Depois abra http://localhost:3000 e registe a primeira conta — numa instância auto-alojada o registo está aberto, e o primeiro utilizador cria o espaço de trabalho.

O primeiro arranque também cria um espaço de trabalho de demonstração com credenciais admin@example.com / changeme123 (e partner@example.com). Altere essa palavra-passe após o primeiro início de sessão, ou defina SEED_PASSWORD em .env antes do primeiro arranque. Não quer os dados de demonstração? Basta registar a sua própria conta e apagar o espaço de trabalho de demonstração.

A aplicação funciona totalmente sem chaves de API externas; as funcionalidades de IA e as ligações de caixas de correio ativam-se à medida que adicionar as credenciais (abaixo).

Para parar: docker compose down (adicione -v para também apagar a base de dados/ficheiros carregados).

Configuração​

Toda a configuração são variáveis de ambiente em .env. bin/generate-secrets trata dos segredos obrigatórios; tudo o resto é opcional. A lista anotada encontra-se em .env.example.

Obrigatórias (geradas para si)​

VariávelNotas
SECRET_KEY_BASEChave de sessão/assinatura do Rails. openssl rand -hex 64
ACTIVE_RECORD_PRIMARY_KEYEncripta tokens OAuth e chaves de IA em repouso. openssl rand -hex 16
ACTIVE_RECORD_DETERMINISTIC_KEYIdem
ACTIVE_RECORD_KEY_DERIVATION_SALTIdem
CAMPBOOKS_DATABASE_PASSWORDPalavra-passe do Postgres incluído

Não precisa de config/master.key — o auto-alojamento lê SECRET_KEY_BASE a partir do ambiente.

Obrigatórias (definidas por si)​

VariávelPredefiniçãoNotas
APP_HOSTlocalhostO hostname pelo qual acede à aplicação. Tem de corresponder ao cabeçalho Host (localhost, um IP ou o seu domínio) — outros hosts são rejeitados por segurança.
FORCE_SSLfalseMantenha false para uso local em HTTP simples. Defina true apenas atrás de um proxy TLS (consulte Produção).
SELF_HOSTED1Registo aberto + lê chaves de IA a partir do ambiente.

Integrações externas​

Todas as integrações são opcionais. Adicione as que pretender; ignore as restantes.

Para cada fornecedor OAuth, tem de registar uma aplicação na consola desse fornecedor e colocar na lista de permissões o URL de callback, que é <url-da-sua-aplicação>/oauth/<fornecedor>/callback — por exemplo, http://localhost:3000/oauth/gmail/callback localmente, ou https://app.example.com/oauth/gmail/callback em produção.

Fornecedores de IA​

A IA é o que torna o Campbooks no Campbooks (triage, o assistente Scout, respostas rascunhadas, análise de documentos, pesquisa semântica) — mas é tudo opcional e desativado até adicionar uma chave. Pode definir chaves aqui para toda a instância, ou deixar cada utilizador introduzir a sua própria em Definições → IA (armazenadas encriptadas por espaço de trabalho).

VariávelAtiva
OPENAI_API_KEYIA de texto + análise de documentos/visão + embeddings (pesquisa semântica). A chave única mais completa.
ANTHROPIC_API_KEYIA de texto (Claude)
MISTRAL_API_KEYIA de texto (alojado na UE)
DEEPSEEK_API_KEYIA de texto
GEMINI_API_KEYIA de texto + embeddings
  • Para o assistente/triage: defina qualquer fornecedor de texto.
  • Para análise de anexos/documentos e a melhor pesquisa: defina OPENAI_API_KEY.
  • Sem fornecedor de embeddings (OpenAI ou Gemini), a pesquisa reverte para correspondência por palavras-chave.

Google — Gmail e Calendário​

Permite que os utilizadores iniciem sessão com o Google e liguem uma caixa de correio Gmail (que também sincroniza o Google Calendar com a mesma autorização).

  1. Google Cloud Console → crie um projeto → APIs & Services → Credentials → OAuth client ID (tipo: Web application).
  2. Ative a Gmail API e a Google Calendar API para o projeto.
  3. Adicione o URI de redirecionamento: <url-da-sua-aplicação>/oauth/gmail/callback.
  4. Defina GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET.

Google Drive — "Enviar para o Drive"​

A exportação interativa para o Drive usa o âmbito completo drive, um âmbito restrito do Google, pelo que precisa da sua própria aplicação OAuth verificada separadamente.

  1. Crie um segundo cliente OAuth (ou um projeto separado).
  2. Adicione o âmbito https://www.googleapis.com/auth/drive e o URI de redirecionamento <url-da-sua-aplicação>/oauth/google/callback.
  3. Defina GOOGLE_DRIVE_CLIENT_ID e GOOGLE_DRIVE_CLIENT_SECRET.

Zoho Mail​

  1. Zoho API Console → Server-based Application.
  2. URI de redirecionamento: <url-da-sua-aplicação>/oauth/zoho/callback.
  3. Defina ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET e ZOHO_REGION (eu, com, in, au, jp — corresponda ao seu centro de dados Zoho).

Microsoft 365 / Outlook​

  1. Centro de administração do Entra → Registos de aplicações → Novo registo. Tipos de conta suportados: Contas em qualquer diretório organizacional (contas profissionais/escolares; a aplicação usa o endpoint /organizations/).
  2. Adicione um URI de redirecionamento Web: <url-da-sua-aplicação>/oauth/microsoft/callback.
  3. Crie um segredo de cliente.
  4. Defina MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET e ENABLE_MICROSOFT_MAILBOX=1 (este último revela o botão "Ligar Microsoft 365").

Notion — "Enviar para o Notion"​

  1. notion.so/my-integrations → nova integração, tipo Public, com capacidades de leitura/inserção de conteúdo.
  2. URI de redirecionamento: <url-da-sua-aplicação>/oauth/notion/callback.
  3. Defina NOTION_CLIENT_ID e NOTION_CLIENT_SECRET.

Se deixar estas variáveis por definir, os utilizadores podem ainda assim ligar o Notion colando um token de integração interna nas Definições.

Email de saída (SMTP)​

Sem SMTP, a aplicação não envia email (códigos OTP de registo, notificações e relatórios são ignorados — aceitável para um teste de utilizador único, mas vai querer isso para uso real).

SMTP_ADDRESS=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=you@example.com
SMTP_PASSWORD=your_smtp_password
MAILER_FROM=Campbooks <no-reply@example.com>

Armazenamento de ficheiros (S3)​

Por omissão, os ficheiros carregados ficam no volume Docker storage. Para usar armazenamento de objetos (recomendado se executar múltiplas réplicas web ou quiser cópias de segurança mais fáceis), defina:

S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_BUCKET=campbooks-storage
S3_REGION=eu-central-1
# Para fornecedores não-AWS (MinIO, Hetzner, Backblaze B2, ...):
S3_ENDPOINT=https://...
S3_FORCE_PATH_STYLE=true

Pesquisa (OpenSearch)​

O OpenSearch é opcional e apenas suporta o autocompletar de texto completo de contactos. A pesquisa de email, pesquisa de documentos e a paleta Cmd+K usam todas Postgres + pgvector e funcionam sem ele; a pesquisa de contactos reverte para correspondência SQL. Para ativá-lo:

# em .env
OPENSEARCH_URL=http://opensearch:9200
docker compose --profile search up -d

Monitorização de erros e push​

  • SENTRY_DSN — um DSN compatível com Sentry (por exemplo, GlitchTip auto-alojado). Desativado se não definido.
  • APNS_* / FCM_* — apenas necessários se compilar as aplicações nativas iOS/Android. Desativados se não definidos.

Executar em produção​

Para qualquer uso além do local, termine o TLS com um proxy reverso e ative o SSL.

  1. Aponte um domínio para o seu servidor e defina, em .env:
    APP_HOST=app.example.com
    FORCE_SSL=true
    WEB_PORT=3000
  2. Coloque um proxy com terminação TLS à frente. Com o Caddy (HTTPS automático) é apenas:
    app.example.com {
    reverse_proxy localhost:3000
    }
    O proxy fala HTTPS para o mundo e encaminha para o contentor na porta :3000; FORCE_SSL=true faz o Rails emitir links https, definir cookies seguros e enviar HSTS. (O endpoint de saúde /up mantém-se acessível em HTTP simples para sondagens.)
  3. docker compose up -d --build.

Não exponha a aplicação em HTTP simples na internet. Com FORCE_SSL=false, as sessões e os cookies viajam sem encriptação. Utilize sempre um proxy TLS em produção.

Cópias de segurança​

Dois elementos mantêm estado: o volume do Postgres e os ficheiros carregados.

# Base de dados (a BD da aplicação; cache/queue/cable são regeneráveis)
docker compose exec -T postgres pg_dump -U campbooks_app cb_primary | gzip > campbooks-$(date +%F).sql.gz

# Ficheiros carregados (apenas se usar armazenamento em disco local, não S3)
docker run --rm -v campbooks_storage:/data -v "$PWD":/backup alpine \
tar czf /backup/campbooks-storage-$(date +%F).tar.gz -C /data .

Guarde as cópias de segurança fora do servidor. Se usar S3 para armazenamento, apenas a base de dados precisa de cópia de segurança aqui.

Atualizações​

git pull
docker compose up -d --build # o entrypoint executa as migrações no arranque

Faça uma cópia de segurança da base de dados primeiro. As migrações executam automaticamente quando o contentor web arranca.

Consola e tarefas​

docker compose exec web bin/rails console
docker compose exec web bin/rails db:seed # dados de demonstração opcionais / login

Resolução de problemas​

Cada pedido redireciona para https:// e falha. FORCE_SSL está ativo mas não há proxy TLS. Defina FORCE_SSL=false para uso local, ou coloque um proxy TLS à frente para produção.

"Blocked hosts" / 403 em todas as páginas. APP_HOST não corresponde à forma como está a aceder à aplicação. Defina-o com o hostname/IP exato na barra de endereços e recrie os contentores.

O web reinicia repetidamente com erro de base de dados/extensão. Certifique-se de que o serviço postgres usa a imagem pgvector/pgvector incluída (uma imagem postgres comum não consegue fazer CREATE EXTENSION vector). Se a trocou, reverta.

O worker regista erros logo após arrancar. Aguarda que o web termine as migrações; os erros transitórios durante o primeiro arranque estabilizam assim que o web estiver saudável.

Segredo obrigatório em falta no docker compose up. Saltou o bin/generate-secrets, ou falta uma chave no .env. Execute novamente o script.