- TypeScript 32%
- HTML 22.3%
- Jinja 20.3%
- Vue 13.3%
- Shell 4.5%
- Other 7.6%
| .gitea/workflows | ||
| base | ||
| local | ||
| textos-tmp | ||
| ansible.cfg | ||
| Readme.md | ||
[nome do pacote]
Pacote de infraestrutura digital para organizações comunitárias: ferramentas livres, auto-hospedadas e integradas por um login único, instaladas num servidor Debian por Ansible e documentadas para que outras organizações possam replicar.
Pensado para ser a infra de pequenos hubs, principalmente organizações, mas incluindo as pessoas em volta delas.
O que é
Um conjunto de playbooks e roles Ansible que, a partir de um arquivo de variáveis, instala e mantém num servidor:
- login único para todos os apps (Authentik), com cadastro de pessoas por convite;
- os apps da organização (planilhas, arquivos, tarefas, site, automações, senhas);
- um painel simples para quem coordena a organização cuidar de pessoas, grupos, dados e backups;
- backup diário com cópia para fora do servidor, restauração testável e alertas.
Rodar o setup.yml de novo aplica só o que mudou: a configuração fica nos arquivos de variáveis, não em ajustes feitos à mão no servidor.
Por que essa abordagem
[placeholder — a seção mais importante do README. A ideia central: entender o problema é mais importante do que entender o código. Cada organização, cada grupo de pessoas tem suas especificidades — fluxos diferentes, dados diferentes, jeitos de funcionar que não cabem em software genérico. O pacote não é uma solução pronta, é um conjunto de ferramentas livres integradas que podem ser organizadas de acordo com a realidade de quem usa.
Por isso a ênfase em:
- Metodologia antes de tecnologia — o processo começa escutando, mapeando como a organização funciona, o que precisa fluir, onde trava. A escolha e configuração das ferramentas vem depois.
- Oficinas e formação — criar e configurar junto, não entregar pronto. O objetivo é quem usa entender o suficiente pra manter, adaptar, mudar. O conhecimento fica na organização, não num prestador de serviço.
- Ferramentas moldáveis — Grist não é uma estrutura fixa, é uma base que se adapta. Node-RED conecta do jeito que fizer sentido. YunoHost simplifica instalar novos serviços. Fractopia pretende ser ainda mais customizável. O ponto é que a estrutura emerge do uso, não é imposta por quem fez o software.
- Documentação como parte da infraestrutura — documentar o que foi feito e por quê, não só como. Pra que outra pessoa (ou a mesma pessoa daqui a seis meses) consiga retomar e ajustar.
A stack foi escolhida por essa flexibilidade. O deploy é descrito em Ansible idempotente: a pessoa declara o que quer em variáveis e roda o playbook quantas vezes precisar, até o servidor chegar ao estado declarado. Em cima dessa base, cada organização monta a configuração que faz sentido pro seu contexto.
O que tem no pacote
Cada app liga ou desliga por install_mode em group_vars. Todos rodam em Docker, atrás do nginx do servidor, e entram pelo Authentik, exceto onde a tabela diz outra coisa.
| App | Para que serve | Endereço padrão | No exemplo |
|---|---|---|---|
| Authentik | Login único (OIDC), grupos, cadastro por convite | auth. |
sempre ligado |
| Grist | Planilhas e bancos de dados, com histórico de versões dos documentos | grist. |
ligado |
| Nextcloud | Arquivos e drive | cloud. |
ligado |
| OnlyOffice Docs | Edição de .docx, .xlsx e .pptx no navegador, a partir do Nextcloud e do Devflow |
office. |
desligado |
| Devflow | Tarefas, kanban, wiki e controle de tempo (construído a partir do repositório do Devflow) | devflow. |
ligado |
| CMS | Site, blog, páginas e agenda; uma instância por site (construído a partir do repositório do CMS) | site. ou domínio próprio |
ligado, login local (sem Authentik ainda) |
| Node-RED | Fluxos e automações entre os apps; só para admin_infra |
fluxos. |
ligado |
| Vaultwarden | Cofre de senhas compartilhado, compatível com os apps do Bitwarden | senhas. |
desligado |
| Painel da organização | Pessoas, convites, grupos, catálogo de dados e situação dos backups (código em base/painel/) |
painel. |
ligado, só para admin_infra |
Serviços de apoio, sem endereço público: MongoDB (Devflow e CMS), RustFS (armazenamento de objetos para o histórico de versões do Grist), Postgres compartilhado (sem consumidor hoje; só sobe se algum banco for declarado), VictoriaLogs (logs do servidor e dos containers num lugar só).
No servidor, o Ansible também cuida de firewall (ufw), Docker, nginx com certificados do Let's Encrypt (certbot), ajustes de segurança do SSH e do journald, backup e alertas.
Fora do pacote por enquanto: Zulip e e-mail próprio (ver base/docs/arquitetura/email-estudo.md).
Como funciona
internet
│ 80/443 (ufw libera só 22, 80, 443)
┌─────────▼──────────┐
│ nginx + certbot │ um domínio por app, HTTPS
└─────────┬──────────┘
│ 127.0.0.1:<porta>
┌─────────▼─────────────────────────────────────────────┐
│ apps em Docker, um projeto Compose por app │
│ Grist · Nextcloud · OnlyOffice · Devflow · CMS │
│ Node-RED · Vaultwarden · Painel │
│ │ login │ dados │
│ ┌─────▼─────┐ ┌──────────────▼──────────────────┐ │
│ │ Authentik │ │ MongoDB · RustFS · Postgres │ │
│ └───────────┘ │ (redes internas, sem porta) │ │
│ └─────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘
Debian 13 · Ansible · backup diário · logs · alertas
- Configuração em arquivo. Tudo o que define o servidor está nas variáveis (
local/ansible/group_vars/all/). O preflight confere as variáveis antes de mexer no servidor. Segredos são gerados na primeira execução e guardados emlocal/state/secrets.yml, na máquina de quem administra. (ADR-001) - Um login para tudo. Cada app ganha no Authentik o seu provedor OIDC e a regra de quem pode entrar (
access_groups), aplicados por blueprint. Pessoas entram por convite e precisam de e-mail. (ADR-002, ADR-003, ADR-004) - Nada exposto além do nginx. Containers publicam porta só em
127.0.0.1; bancos ficam em redes internas, sem porta. Cada container roda com limites de memória, CPU e processos. - Imagens com versão fixa. Nada de
latest; apps construídos a partir do código-fonte (Devflow, CMS) usam um commit fixado.
Estado
- O conjunto padrão (firewall, Docker, nginx + certbot, Authentik, Grist, Nextcloud, Devflow, painel, backup local e remoto com restauração) foi validado em servidor real em set/2026: duas execuções seguidas sem mudança, login pelo navegador, teste de backup → perda → restore e cópia para o BorgBase.
- Em out/2026: Node-RED com login pelo Authentik e Vaultwarden validados em servidor; OnlyOffice no ar, abrindo documentos pelo Nextcloud. Faltam o restore e as organizações do Vaultwarden, e salvar, reabrir e usar no celular no OnlyOffice.
- Sem validação completa: o CMS (já roda num servidor real) e o backup com
restic. - RustFS (no lugar do MinIO, que deixou de ser distribuído): role e migração testadas com Docker na máquina de desenvolvimento; falta validar no servidor de teste e migrar os dois servidores que ainda rodam o MinIO (
base/docs/validacao-rustfs.md). - Login pelo Authentik no CMS: planejado (
base/docs/arquitetura/oidc-no-cms.md). - Nome do pacote e licença: ainda não definidos.
Fases e pendências: base/docs/arquitetura/roadmap-implementacao.md.
Pré-requisitos
- Servidor: Debian 12 ou 13 limpo (validado em 13) (VPS ou máquina física) com acesso SSH como
rootou comsudo. 4 GB de RAM para o conjunto padrão (o build do Devflow e do CMS roda no próprio servidor); o OnlyOffice pede mais 1 a 2 GB livres. Portas 22, 80 e 443 alcançáveis da internet. - Domínio: um registro DNS apontando para o servidor para
auth.<domínio>e para cada app ligado. Osetup.ymlconfere o DNS antes de pedir os certificados e para se faltar algum. - Máquina de controle: Ansible 2.15 ou mais novo, as collections de
base/ansible/requirements.ymle uma chave SSH que entra no servidor.
Instalação
ansible-galaxy collection install -r base/ansible/requirements.yml
mkdir -p local/ansible/group_vars/all
cp base/ansible/inventory.example.yml local/ansible/inventory.yml
cp base/ansible/group_vars/all.example.yml local/ansible/group_vars/all/main.yml
# editar: domínio, e-mail, apps ligados e o commit (build.ref) do Devflow e do CMS
ansible-playbook -i local/ansible/inventory.yml base/ansible/playbooks/setup.yml
Na primeira vez, use certificado de teste (infra_tls.staging: true) e rode o setup.yml duas vezes: a segunda deve terminar com changed=0. A pasta local/ não vai para o Git (exceto o README dela) e guarda inventário, variáveis e segredos da instalação.
Passo a passo completo, onde fica cada coisa no servidor e solução de problemas: base/docs/Como usar.md. Referência das roles: base/ansible/README.md. Exemplo com todos os apps ligados: base/ansible/examples/organizacao-completa/.
Operação
| Playbook | O que faz |
|---|---|
setup.yml |
Instala e aplica mudanças de configuração |
convite.yml |
Cria um convite de cadastro e imprime o link (também dá para convidar pelo painel) |
health.yml |
Confere containers, domínios, certificados e disco |
backup.yml |
Roda um backup na hora |
restore.yml |
Restaura um backup guardado no servidor |
restore-remoto.yml |
Busca uma cópia num destino remoto e restaura, inclusive numa VPS nova |
- Backup: diário (03h30), com dumps dos bancos e dados de cada app ligado em
/srv/infra-comunitaria/backups/, guardados por 14 dias. Cada backup é copiado para os destinos deinfra_backup.destinos: Borg criptografado (BorgBase ou servidor SSH), rsync para um disco de confiança ou restic. Backup só conta depois de um restore testado (base/docs/validacao-fatia-vertical.md). - Alertas: de hora em hora o servidor confere containers, disco, certificados, idade do último backup e erros 5xx, e avisa por ntfy se configurado.
- Logs: containers e nginx escrevem no journald; o VictoriaLogs indexa por 30 dias (limite de 2 GiB). Logs não entram no backup.
Estrutura do repositório
Readme.md
ansible.cfg # aponta para as roles; rode os playbooks da raiz
base/
├── ansible/
│ ├── playbooks/ # setup, convite, health, backup, restore, restore-remoto, migrar-minio-rustfs
│ ├── roles/ # preflight, secrets, common, firewall, docker, reverse_proxy,
│ │ # identity (Authentik), postgres, mongodb, rustfs, logs, backup,
│ │ # app_grist, app_nextcloud, app_onlyoffice, app_devflow,
│ │ # app_cms, app_automation (Node-RED), app_vaultwarden, app_painel
│ ├── group_vars/ # all.example.yml e vault.example.yml: modelos de configuração
│ └── examples/ # organizacao-completa: exemplo com todos os apps
├── painel/ # painel da organização (Nuxt 3), construído pela role app_painel
├── docs/
│ ├── Como usar.md # guia de instalação e operação
│ ├── adr/ # decisões de arquitetura (001 a 004)
│ ├── arquitetura/ # como cada parte funciona e por quê
│ └── validacao-*.md # roteiros de teste em servidor
├── scripts/
│ ├── ci/ # teste de integração numa VPS descartável (ci-fatia.sh)
│ └── *.sh # apoio ao protótipo Compose
├── compose/ # protótipo Compose antigo, só para teste local; não usar em produção
├── grist-widgets/examples/ # protótipos de widgets do Grist (HTML)
└── spikes/navegador-dados/ # protótipo do catálogo de dados que virou a seção Dados do painel
local/ # configuração e segredos de cada instalação (fora do Git)
textos-tmp/ # rascunhos
Documentação
base/docs/Como usar.md: instalação, operação do dia a dia, backup e restore, Vaultwarden, OnlyOffice, sintomas e soluções.base/docs/adr/: Ansible como forma de instalação, Authentik como identidade, OIDC em todos os apps, cadastro por convite com e-mail obrigatório.base/docs/arquitetura/: deploy, identidade e usuários, proxy e firewall, segredos, backup remoto, logs, limites dos containers, atualizações, armazenamento de objetos (RustFS) e Grist, painel, fichas técnicas dos apps, roadmap.base/docs/validacao-*.md: roteiros para validar o pacote, o CMS, o Vaultwarden, o OnlyOffice e o RustFS num servidor.
Contexto
Desenvolvido no contexto do projeto LabLab, no Vale do Paraíba, como parte de um trabalho mais amplo e a longo prazo de infraestrutura comunitária e tecnologia participativa.
Licença
Ainda não definida.