↓Pular para o conteúdo principal
  1. blog/
ARTIGO TÉCNICO

Backup do Semaphore não é só pg_dump: o que precisa existir para recuperar o control plane

Como pensar o backup de um Semaphore self-hosted quando banco, secrets, SSH, configurações cloud e arquivos da stack participam da recuperação.

Quando Semaphore vira control plane de automação, perder a instância não significa apenas perder uma interface web.

Você pode perder:

  • projetos;
  • templates;
  • histórico de tasks;
  • inventories;
  • environments/Variable Groups;
  • referências de keys;
  • configuração da stack;
  • arquivos necessários para o executor voltar a funcionar.

Na implementação privada que originou este artigo, o backup já refletia isso: fazia pg_dump do PostgreSQL e também empacotava partes operacionais do diretório da stack.

O aprendizado é simples:

backup do banco é necessário, mas não necessariamente suficiente para recuperar o control plane.

O PostgreSQL é o núcleo do estado da aplicação #

O primeiro artefato é um dump lógico.

Conceitualmente:

1
2
3
4
pg_dump \
  -h db \
  -U semaphore \
  semaphore > semaphore.sql

Na stack real, o script executa o dump através do container do PostgreSQL.

A vantagem do dump lógico é ter um artefato restaurável sem depender de copiar o volume com o banco em execução.

Isso não elimina a necessidade de testar compatibilidade e restore.

Mas o banco não contém todo o ambiente #

O diretório operacional também inclui material como:

1
2
3
4
5
6
7
Compose/Dockerfile
configuração
Ansible config
SSH
AWS/OCI config
secrets
outros arquivos de runtime necessários

Parte disso não deve estar no Git justamente por ser sensível.

Se a máquina morrer e só o repositório for restaurado, a stack pode subir sem conseguir autenticar nos destinos.

Secrets tornam o backup mais sensível que o código #

Se o pacote de backup inclui:

  • senha do banco;
  • chaves de criptografia/cookies;
  • SSH keys;
  • configuração cloud;

então o backup passa a ter valor equivalente — ou maior — que o próprio diretório operacional.

Isso muda a política de armazenamento.

Eu não colocaria esse tarball em bucket público, artifact aberto ou Git release.

No mínimo, precisa de:

  • acesso restrito;
  • armazenamento fora do host de origem;
  • criptografia adequada ao ambiente;
  • retenção definida;
  • auditoria de acesso.

A fonte recuperada comprova retenção local; controles adicionais precisam ser validados separadamente antes de serem apresentados como existentes.

Backup local protege de erro lógico, não de perda do host #

A rotina real mantém arquivos por uma janela local.

Isso é útil contra:

  • erro recente;
  • arquivo removido;
  • necessidade de voltar alguns dias.

Mas se backup e produção estão no mesmo disco/servidor, ambos compartilham vários modos de falha.

Uma estratégia de continuidade precisa pensar em uma segunda cópia fora do host.

Não estou afirmando que a implementação analisada já possua essa segunda cópia; é a evolução natural do desenho.

Restore começa pela ordem das dependências #

Eu documentaria o restore em camadas.

1. Preparar host/runtime #

1
2
3
Docker/Compose
rede do proxy
paths e permissões

2. Restaurar arquivos privados #

1
2
3
4
secrets
SSH
config AWS/OCI
configuração Ansible

3. Subir PostgreSQL #

Aguardar health check.

4. Restaurar banco #

Exemplo conceitual:

1
psql -U semaphore semaphore < semaphore.sql

5. Subir Semaphore #

6. Validar aplicação #

7. Validar executor #

1
2
3
4
ansible --version
SSH para alvo de teste
AWS/OCI read-only smoke
Git checkout

O restore não termina quando a tela de login abre.

Uma interface funcionando pode esconder executor quebrado #

É possível recuperar PostgreSQL e UI, mas esquecer:

  • private key SSH;
  • known_hosts/config;
  • profile cloud;
  • variável de criptografia;
  • diretório/permission necessário para task.

Nesse estado, o Semaphore parece saudável até a primeira execução.

Por isso eu separo:

1
2
3
health do control plane
+
health do executor

Smoke pós-restore #

Antes de liberar mudanças reais:

1
ansible localhost -m ping -c local

Depois um target de teste/read-only.

Para cloud:

1
2
aws --version
oci --version

E operações de identidade/leitura apropriadas.

Para Git, um template smoke que faça checkout do repositório sem executar mudança.

Backup precisa acompanhar mudança de arquitetura #

Se amanhã a stack passar a usar:

  • S3 para artifacts;
  • Vault externo;
  • Redis;
  • outro DB;
  • inventory dinâmico;
  • runners separados;

os limites do backup mudam.

Por isso prefiro documentar componentes de estado em vez de manter uma lista fixa de diretórios sem contexto.

Uma tabela útil:

1
2
3
4
5
6
7
Componente              Fonte de verdade       Backup necessário?
Banco Semaphore         PostgreSQL             sim
Código/Compose           Git                    reconstruível
Secrets                  filesystem/vault       sim ou via fonte externa
SSH/config cloud         filesystem/secret mgr  sim ou reconstruível
Logs históricos          plataforma             conforme retenção
Runtime efêmero          runtime                normalmente não

Runtime de jobs merece outra decisão #

A fonte privada possui diretórios com artefatos de jobs de resize/agendamento.

Nem todo runtime precisa entrar em restore permanente.

É preciso distinguir:

1
estado necessário para continuar operação

de:

1
artefato temporário/auditável que pode ter retenção própria

Copiar tudo indefinidamente aumenta risco de dados sensíveis e lixo operacional.

Não publique o backup como “exemplo” #

Quando criarmos um blueprint público do Semaphore, backup e restore devem ser demonstrados com:

  • nomes fictícios;
  • secrets placeholders;
  • banco de demonstração;
  • paths genéricos.

Nunca reutilizando um backup real sanitizado “na mão”.

Backup tende a concentrar exatamente o material que o repo público precisa excluir.

O que a fonte sustenta #

O semaphore-migre privado contém uma rotina que:

  • executa pg_dump do PostgreSQL do Semaphore;
  • cria pacote com arquivos operacionais da stack;
  • inclui material de configuração necessário para recuperação;
  • mantém retenção local por dias;
  • trata secrets/SSH/cloud config como parte do material operacional privado.

A fonte não é usada para afirmar criptografia offsite, teste periódico de restore ou uma política de DR completa que ainda não foi comprovada.

Checklist de continuidade #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[ ] dump lógico do banco
[ ] arquivos de infraestrutura versionados
[ ] secrets recuperáveis
[ ] SSH/config cloud recuperáveis
[ ] cópia fora do host
[ ] criptografia/acesso do backup
[ ] retenção
[ ] runbook de restore
[ ] teste de login
[ ] smoke do executor
[ ] smoke Git/SSH/cloud
[ ] revisão após mudanças de arquitetura

O principal aprendizado #

Backup de um control plane precisa recuperar a capacidade de executar com segurança, não apenas a capacidade de abrir a interface.

Para Semaphore, isso significa pensar no conjunto:

1
2
3
4
5
6
7
8
9
banco
+
configuração
+
segredos
+
identidade do executor
+
validação pós-restore

Se só o PostgreSQL voltou, a recuperação ainda não terminou.

TEM UM CENÁRIO PARECIDO?

Me chama.

Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.

Falar com Castro →
Sem enrolação. Com evidência.