Git para Sysadmins: Controlo de Versões de Configuração em 2026
SCHEMA MARKUP JSON-LD | ✎ Duarte Spínola | Tags:
Sysadmins gerem dezenas de ficheiros de configuração — Nginx, Postfix, Docker Compose, scripts PowerShell, cron jobs, Ansible playbooks. Quando algo para de funcionar, a primeira pergunta é “o que mudou?”. Sem controlo de versões, a resposta é “não sei”. Com Git, cada alteração fica registada com autor, data e mensagem. Este artigo mostra como usar Git para gerir configuração de servidores, com repositórios remotos, branching para mudanças, e integração com Ansible — sem ser developer (Git docs).
Neste artigo
- Entender Git para Configuração de Sistemas
- Pré-requisitos e Instalação
- Passo 1 — Inicializar Repositório de Configuração
- Passo 2 — Trabalhar com Repositório Remoto (Gitea/GitHub)
- Passo 3 — Branching para Mudanças em Produção
- Passo 4 — Hooks e Deploy Automático
- Passo 5 — Git com Ansible
- Passo 6 — Auditoria e Histórico de Mudanças
- Git vs Outras Abordagens — Comparação
- Erros Comuns
- Checklist Rápido de Verificação
1. Entender Git para Configuração de Sistemas
Git é um sistema de controlo de versões distribuído. Cada ficheiro tem histórico completo de alterações. Podes voltar a qualquer versão anterior, ver quem mudou o quê e quando, e mergear mudanças de múltiplas pessoas sem conflitos.
Analogia: Git é como um caderno de registos com fotocopiadora integrada. Cada vez que alteras uma página, o caderno guarda a versão anterior. Se alguém altera a mesma página noutro caderno, a fotocopiadora mergeia as duas versões. Se algo corre mal, voltas à página de ontem em 2 segundos.
| Conceito Git | Equivalente sysadmin | Utilidade |
|---|---|---|
| Repository (repo) | Pasta de configuração com histórico | Guardar todos os configs num só sítio |
| Commit | Snapshot de uma alteração | “Mudei a porta do Nginx de 80 para 8080” |
| Branch | Linha paralela de mudanças | Testar mudanças sem afectar produção |
| Merge | Juntar branch na linha principal | Aplicar mudanças testadas em produção |
| Remote | Cópia do repo noutro servidor | Backup + colaboração |
| Clone | Cópia local do repo | Trabalhar offline no servidor |
| Pull / Push | Sincronizar mudanças | Enviar configs para o servidor central |
| .gitignore | Lista de ficheiros a ignorar | Não versionar secrets, logs, caches |
Para sysadmins, Git resolve três problemas concretos:
- “O que mudou?” —
git logmostra todas as alterações com data e autor - “Como voltar atrás?” —
git checkoutrestaura qualquer versão anterior - “Quem fez isto?” —
git blamemostra quem alterou cada linha (Git Pro book)
2. Pré-requisitos e Instalação
| Requisito | Detalhe |
|---|---|
| Git | 2.40+ (qualquer versão recente) |
| Editor de texto | vim, nano, ou VS Code |
| Servidor remoto (opcional) | Gitea self-hosted, GitHub, GitLab |
| SSH key | Para autenticação com remoto |
Instalar Git:
Ubuntu/Debian:
Fedora/RHEL:
Arch Linux:
macOS:
Se brew não estiver instalado, instalar primeiro: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)".
Configurar identidade (uma vez por máquina):
git config –global user.email “[email protected]”
git config –global init.defaultBranch main
O que cada config faz:
user.name— nome que aparece em cada commituser.email— email que aparece em cada commitinit.defaultBranch main— usamainem vez demastercomo branch inicial (convenção moderna)
3. Passo 1 — Inicializar Repositório de Configuração
Criar um repositório para guardar a configuração de todos os servidores:
cd /srv/git/configs
sudo git init
Criar estrutura de pastas por servidor:
Copiar configs actuais para o repositório:
sudo cp /etc/nginx/sites-available/* nginx/
sudo cp /etc/postfix/main.cf postfix/
sudo cp -r /etc/ansible/playbooks/* ansible/
Criar .gitignore para excluir ficheiros sensíveis:
*.key
*.pem
*.p12
.env
shadow
passwd
# Logs
*.log
*.log.*
# Caches
__pycache__/
*.pyc
.vagrant/
EOF
O que o .gitignore faz: diz ao Git para ignorar estes ficheiros — nunca os committa, nunca os envia para o remoto. Ficheiros .key e .pem contêm chaves privadas que NUNCA devem ir para um repositório Git (Git ignore docs).
⚠️ Atenção
Se já fizeste commit de um ficheiro secret, removê-lo do .gitignore não apaga o histórico. Usar git filter-branch ou BFG Repo-Cleaner para remover do histórico. Depois rodar todas as chaves comprometidas.
Fazer o primeiro commit:
sudo git commit -m “Estado inicial: configs nginx, postfix, ansible, cron”
O que cada comando faz:
git add .— adiciona todos os ficheiros da pasta ao staging area (ficheiros a serem commitados)git commit -m— regista um snapshot com mensagem descritiva
4. Passo 2 — Trabalhar com Repositório Remoto (Gitea)
Para backup e colaboração, configurar um repositório remoto. Gitea é leve e self-hosted — ideal para PME.
Instalar Gitea com Docker:
-p 3000:3000 \
-p 2222:22 \
-v /srv/gitea:/data \
–restart always \
gitea/gitea:latest
O que cada parâmetro faz:
-p 3000:3000— porta web do Gitea-p 2222:22— porta SSH para git push/pull-v /srv/gitea:/data— persiste dados do Gitea no host--restart always— reinicia automaticamente se o Docker ou o servidor reiniciar
No Gitea (acessível em http://servidor:3000), criar utilizador e repositório configs. Depois ligar o repo local ao remoto:
sudo git push -u origin main
O que cada comando faz:
git remote add origin— define o servidor remoto onde o repo vai ser sincronizadogit push -u origin main— envia a branchmainpara o remoto e define upstream (futuregit pushsem argumentos)
5. Passo 3 — Branching para Mudanças em Produção
Antes de alterar uma config em produção, criar uma branch para testar:
sudo git checkout -b feature/nginx-rate-limiting
O checkout -b cria uma nova branch e muda para ela imediatamente. A branch main fica intacta.
Fazer as alterações necessárias:
# Adicionar rate limiting no bloco http
Commitar as mudanças na branch:
sudo git commit -m “Adicionar rate limiting no Nginx (100 rps por IP)”
Para aplicar em produção, fazer merge para main:
sudo git merge feature/nginx-rate-limiting
E copiar a config para o local de produção:
sudo nginx -t && sudo systemctl reload nginx
ℹ️ Nota: O nginx -t testa a configuração sem recarregar — sempre correr antes de reload. Se o teste falhar, NÃO fazer reload.
6. Passo 4 — Hooks e Deploy Automático
Git hooks são scripts que correm automaticamente em eventos Git. O hook post-merge pode deployar configs automaticamente:
# Deploy automático após merge
# Nginx
if git diff –name-only HEAD@{1} HEAD | grep -q “^nginx/”; then
cp nginx/nginx.conf /etc/nginx/nginx.conf
cp nginx/sites-available/* /etc/nginx/sites-available/
nginx -t && systemctl reload nginx
echo “Nginx config deployed and reloaded”
fi
# Postfix
if git diff –name-only HEAD@{1} HEAD | grep -q “^postfix/”; then
cp postfix/main.cf /etc/postfix/main.cf
postfix check && systemctl reload postfix
echo “Postfix config deployed and reloaded”
fi
# Ansible
if git diff –name-only HEAD@{1} HEAD | grep -q “^ansible/”; then
echo “Ansible playbooks updated — run manually: ansible-playbook ansible/site.yml”
fi
EOF
sudo chmod +x /srv/git/configs/.git/hooks/post-merge
O que o hook faz:
- Verifica que ficheiros mudaram entre o estado anterior e o actual (
git diff --name-only) - Se ficheiros na pasta
nginx/mudaram, copia para/etc/nginx/e recarrega - Se ficheiros na pasta
postfix/mudaram, copia para/etc/postfix/e recarrega - Para Ansible, apenas avisa (não corre playbooks automaticamente — demasiado perigoso)
7. Passo 5 — Git com Ansible
O Ansible já usa ficheiros YAML para playbooks. Combinar com Git dá versionamento completo de automação.
Estrutura recomendada:
├── inventory/
│ ├── production.yml
│ └── staging.yml
├── group_vars/
│ ├── all.yml
│ └── webservers.yml
├── playbooks/
│ ├── site.yml
│ ├── nginx.yml
│ └── security-hardening.yml
├── roles/
│ ├── nginx/
│ ├── postfix/
│ └── common/
└── ansible.cfg
Workflow:
- Criar branch para nova role ou playbook
- Testar com
ansible-playbook --check(dry run) - Aplicar em staging
- Merge para
maine aplicar em produção
ansible-playbook playbooks/nginx.yml –check –diff -i inventory/staging.yml
# Aplicar em staging
ansible-playbook playbooks/nginx.yml -i inventory/staging.yml
# Se OK, merge e aplicar em produção
git checkout main
git merge feature/nginx-role
ansible-playbook playbooks/nginx.yml -i inventory/production.yml
O --check simula mudanças sem as aplicar. O --diff mostra o que mudaria em cada ficheiro. Em produção, sempre fazer --check --diff primeiro (Ansible docs).
8. Passo 6 — Auditoria e Histórico de Mudanças
Ver histórico de alterações
Output típico:
* b8d1f4a atualizar postfix main.cf — relay para Microsoft 365
* c2e9a8b Estado inicial: configs nginx, postfix, ansible, cron
Ver quem alterou uma linha específica
Mostra, para cada linha: commit hash, autor, data, e conteúdo da linha.
Ver o que mudou entre dois commits
Mostra as diferenças na pasta nginx/ entre o commit inicial e o actual.
Voltar a uma versão anterior de um ficheiro
Restaura o nginx.conf para a versão do commit c2e9a8b. Depois commitar a reversão:
9. Git vs Outras Abordagens — Comparação
| Abordagem | Tracking | Backup | Rollback | Colaboração | Auditoria |
|---|---|---|---|---|---|
| Git | Completo | Sim (remoto) | Instantâneo | Sim | Excelente |
| Backups manuais | Nenhum | Sim | Lento | Não | Fraca |
| Pasta de versões | Básico | Sim | Manual | Não | Fraca |
| etckeeper (Git em /etc) | Completo | Sim (remoto) | Instantâneo | Sim | Excelente |
| Ansible sem Git | Nenhum | Nenhum | Não | Não | Nenhuma |
etckeeper é uma ferramenta que automaticamente faz commit de /etc/ após cada alteração com apt/dnf. Para PME que quer zero esforço:
# Auto-inicializa repo Git em /etc e auto-commits após cada package install
10. Erros Comuns
| Problema | Causa | Solução |
|---|---|---|
git push rejeitado |
Remote tem commits que não tens localmente | git pull --rebase origin main antes de push |
| Merge conflict | Dois commits alteraram as mesmas linhas | Editar ficheiro, resolver conflitos (<<<<<<< ======= >>>>>>>), depois git add + git commit |
| Ficheiro secret no histórico | Commit acidental de .key ou .env | git filter-branch --tree-filter 'rm -f ficheiro.key' HEAD ou BFG Repo-Cleaner |
git status mostra ficheiros que não queres |
.gitignore mal configurado | Adicionar padrão ao .gitignore. Se já tracked: git rm --cached ficheiro |
| Hook não executa | Sem permissão de execução | chmod +x .git/hooks/post-merge |
| Perdi o meu trabalho | Commit esquecido antes de mudar de branch | git stash guarda mudanças não commitadas. git stash pop recupera |
detached HEAD |
Checkout de um commit em vez de branch | Criar branch: git checkout -b nova-branch |
| Push para branch errada | git push origin develop em vez de main |
Verificar branch actual com git branch antes de push |
11. Checklist Rápido de Verificação
- [ ] Git instalado e identidade configurada (
git config --global) - [ ] Repositório inicializado em
/srv/git/configs - [ ]
.gitignoreconfigurado (secrets, logs, caches) - [ ] Estrutura de pastas por serviço (nginx/, postfix/, ansible/)
- [ ] Repositório remoto configurado (Gitea ou GitHub)
- [ ]
git pushfunciona sem erros - [ ] Hook
post-mergeconfigurado para deploy automático - [ ] Branch de teste criada antes de alterar produção
- [ ]
nginx -t/postfix checkantes de reload - [ ] Histórico limpo:
git log --onelinemostra mensagens descritivas
Artigos Relacionados
- Ansible: Automatização de PME em 2026 — Usar os playbooks versionados no Git com Ansible
- Linux Server Hardening Checklist 2026 — Hardening que deve ser versionado no Git
- PowerShell 7 para Sysadmin: 15 Scripts de automação — Scripts PowerShell que beneficiam de Git
- Proxmox VE para PME 2026 — Versionar configs de VMs Proxmox
- SIEM para PME 2026: Graylog + Sentinel — Auditoria de mudanças via SIEM correlacionada com Git
