Guia de 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ço | O que é |
|---|---|
postgres | PostgreSQL com a extensão pgvector (obrigatória) |
web | A aplicação Rails (Puma atrás do Thruster) |
worker | Tarefas 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)
opensslna 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ável | Notas |
|---|---|
SECRET_KEY_BASE | Chave de sessão/assinatura do Rails. openssl rand -hex 64 |
ACTIVE_RECORD_PRIMARY_KEY | Encripta tokens OAuth e chaves de IA em repouso. openssl rand -hex 16 |
ACTIVE_RECORD_DETERMINISTIC_KEY | Idem |
ACTIVE_RECORD_KEY_DERIVATION_SALT | Idem |
CAMPBOOKS_DATABASE_PASSWORD | Palavra-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ável | Predefinição | Notas |
|---|---|---|
APP_HOST | localhost | O 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_SSL | false | Mantenha false para uso local em HTTP simples. Defina true apenas atrás de um proxy TLS (consulte Produção). |
SELF_HOSTED | 1 | Registo 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ável | Ativa |
|---|---|
OPENAI_API_KEY | IA de texto + análise de documentos/visão + embeddings (pesquisa semântica). A chave única mais completa. |
ANTHROPIC_API_KEY | IA de texto (Claude) |
MISTRAL_API_KEY | IA de texto (alojado na UE) |
DEEPSEEK_API_KEY | IA de texto |
GEMINI_API_KEY | IA 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).
- Google Cloud Console → crie um projeto → APIs & Services → Credentials → OAuth client ID (tipo: Web application).
- Ative a Gmail API e a Google Calendar API para o projeto.
- Adicione o URI de redirecionamento:
<url-da-sua-aplicação>/oauth/gmail/callback. - Defina
GOOGLE_CLIENT_IDeGOOGLE_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.
- Crie um segundo cliente OAuth (ou um projeto separado).
- Adicione o âmbito
https://www.googleapis.com/auth/drivee o URI de redirecionamento<url-da-sua-aplicação>/oauth/google/callback. - Defina
GOOGLE_DRIVE_CLIENT_IDeGOOGLE_DRIVE_CLIENT_SECRET.
Zoho Mail
- Zoho API Console → Server-based Application.
- URI de redirecionamento:
<url-da-sua-aplicação>/oauth/zoho/callback. - Defina
ZOHO_CLIENT_ID,ZOHO_CLIENT_SECRETeZOHO_REGION(eu,com,in,au,jp— corresponda ao seu centro de dados Zoho).
Microsoft 365 / Outlook
- 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/). - Adicione um URI de redirecionamento Web:
<url-da-sua-aplicação>/oauth/microsoft/callback. - Crie um segredo de cliente.
- Defina
MICROSOFT_CLIENT_ID,MICROSOFT_CLIENT_SECRETeENABLE_MICROSOFT_MAILBOX=1(este último revela o botão "Ligar Microsoft 365").
Notion — "Enviar para o Notion"
- notion.so/my-integrations → nova integração, tipo Public, com capacidades de leitura/inserção de conteúdo.
- URI de redirecionamento:
<url-da-sua-aplicação>/oauth/notion/callback. - Defina
NOTION_CLIENT_IDeNOTION_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.
- Aponte um domínio para o seu servidor e defina, em
.env:APP_HOST=app.example.comFORCE_SSL=trueWEB_PORT=3000 - Coloque um proxy com terminação TLS à frente. Com o Caddy (HTTPS automático) é apenas:
O proxy fala HTTPS para o mundo e encaminha para o contentor na portaapp.example.com {reverse_proxy localhost:3000}
:3000;FORCE_SSL=truefaz o Rails emitir links https, definir cookies seguros e enviar HSTS. (O endpoint de saúde/upmantém-se acessível em HTTP simples para sondagens.) 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.