feat(proxy): Implement Zero-Downtime Reload Strategy

- Added scripts/reload.sh and reload.ps1 for safe configuration updates
- Implemented 'nginx -t' validation before reload to prevent crashes
- Leveraged 'nginx -s reload' for process-level Blue-Green updates
- Updated documentation (README.md, GEMINI.md) with new usage instructions
- Fixed nginx.conf to properly scope snippet includes
- Restored missing SSL components (options-ssl-nginx.conf, dhparams) to enable local validation
This commit is contained in:
João Pedro 2026-01-22 16:39:02 -03:00
parent d9a0b14d6f
commit 3a5d73a485
9 changed files with 88 additions and 3 deletions

View File

@ -117,6 +117,13 @@ docker compose logs nginx-proxy | grep "SSL"
docker compose exec nginx-proxy /scripts/renew_ssl.sh docker compose exec nginx-proxy /scripts/renew_ssl.sh
``` ```
**Reload Zero-Downtime (Blue-Green Logic):**
Este comando valida a configuração e executa um reload gracioso (`nginx -s reload`), onde novos workers assumem as novas configurações enquanto os antigos terminam as requisições correntes.
```bash
./scripts/reload.sh # Linux
./scripts/reload.ps1 # Windows PowerShell
```
**Banir um IP manualmente:** **Banir um IP manualmente:**
```bash ```bash
docker compose exec fail2ban fail2ban-client set nginx-badbots banip 1.2.3.4 docker compose exec fail2ban fail2ban-client set nginx-badbots banip 1.2.3.4

View File

@ -14,5 +14,6 @@
## 3. Atualizações Zero-Downtime (Sem Queda) ## 3. Atualizações Zero-Downtime (Sem Queda)
**Objetivo:** Criar um método para atualizar configurações de sites sem que clientes externos percam a conexão. **Objetivo:** Criar um método para atualizar configurações de sites sem que clientes externos percam a conexão.
- **Cenário Atual:** Restart do container ou reload podem causar breves interrupções se não gerenciados corretamente. - **Status:** ✅ Concluído.
- **Solução Proposta:** Implementar scripts de "Reload Suave" (`nginx -s reload`) com validação prévia (`nginx -t`) automatizada, garantindo que conexões ativas terminem graciosamente. - **Solução Implementada:** Script `./scripts/reload.sh` que executa `nginx -t` e `nginx -s reload` (Reload Suave/Process-Level Blue-Green).
- **Como usar:** Execute `./scripts/reload.sh` após alterar qualquer `.conf`.

View File

@ -111,6 +111,12 @@ O sistema gerencia isso automaticamente, mas você pode intervir manualmente se
docker compose exec nginx-proxy /scripts/renew_ssl.sh docker compose exec nginx-proxy /scripts/renew_ssl.sh
``` ```
- **Reload sem Downtime (Recomendado)**:
Para aplicar alterações de configuração (vhosts, SSL) sem derrubar conexões ativas:
```bash
./scripts/reload.sh
```
### 5. Monitorar e Debugar ### 5. Monitorar e Debugar
- **Verificar Status dos Containers**: - **Verificar Status dos Containers**:

View File

@ -0,0 +1,7 @@
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View File

@ -0,0 +1,8 @@
-----BEGIN DH PARAMETERS-----
MIIBDAKCAQEA7aEz2xmnoIbgtStbhLjO2kIgHb+mXbTBJi2aXSnMlih9Q2WWfEOY
TrSw98BLop6l/6FS9XqCNAaB06AQLYIrXx1V3MtT1x9JcHfwbgKacDsEf+B+yYXS
Avv8G6j6t4k0s7ovg9tVEpRr1n8YCDj1bWv1iiQjfotmzeex6NNE9rX31GvRpRhP
jY+I9JDU0xG7GA16dNYYkq7kNPF7f1HmpFZOPiqox+IoMxZPlMZsKfRxmWpNPbgy
Pmzbrf7i3Wj9gjjGbPSvJ5dnaz4XGqUxAXemAXhjQ9TLVEig2NNo8LeYp/1r22+H
Wls/ddseH7N2lOr3M4oHsaUo4vsKG/SAfwIBAgICAOE=
-----END DH PARAMETERS-----

Binary file not shown.

View File

@ -29,7 +29,13 @@ http {
ssl_session_cache shared:SSL:60m; ssl_session_cache shared:SSL:60m;
# Include Snippets # Include Snippets
include /etc/nginx/snippets/*.conf; # Include Snippets (Global HTTP context)
# Excludes acme_challenge.conf which is server-context only
include /etc/nginx/snippets/cache_zones.conf;
include /etc/nginx/snippets/log_formats.conf;
include /etc/nginx/snippets/rate_limit.conf;
include /etc/nginx/snippets/security_maps.conf;
# include /etc/nginx/snippets/custom_errors.conf; # Optional globally
# Global Fallback Logs # Global Fallback Logs
error_log /var/log/nginx/error.log warn; error_log /var/log/nginx/error.log warn;

24
scripts/reload.ps1 Normal file
View File

@ -0,0 +1,24 @@
$ContainerName = "nginx-proxy"
Write-Host "[Reload] Checking configuration in $ContainerName..." -ForegroundColor Cyan
# 1. Validate Configuration
docker exec $ContainerName nginx -t
if ($LASTEXITCODE -eq 0) {
Write-Host "[Reload] Configuration is VALID." -ForegroundColor Green
# 2. Graceful Reload
Write-Host "[Reload] Triggering graceful reload..." -ForegroundColor Cyan
docker exec $ContainerName nginx -s reload
if ($LASTEXITCODE -eq 0) {
Write-Host "[Reload] ✅ Reload signal sent successfully." -ForegroundColor Green
Write-Host "[Reload] Zero-downtime update in progress." -ForegroundColor Green
} else {
Write-Host "[Reload] ❌ Failed to send reload signal." -ForegroundColor Red
exit 1
}
} else {
Write-Host "[Reload] ❌ Configuration is INVALID. Aborting reload." -ForegroundColor Red
exit 1
}

26
scripts/reload.sh Normal file
View File

@ -0,0 +1,26 @@
#!/bin/bash
# Zero-Downtime Reload Script
# Validates config first, then reloads NGINX gracefully.
CONTAINER_NAME="nginx-proxy"
echo "[Reload] Checking configuration in $CONTAINER_NAME..."
# 1. Validate Configuration (nginx -t)
if docker exec "$CONTAINER_NAME" nginx -t; then
echo "[Reload] Configuration is VALID."
else
echo "[Reload] ❌ Configuration is INVALID. Aborting reload."
exit 1
fi
# 2. Graceful Reload (nginx -s reload)
# This starts new workers with new config, while old workers finish requests.
echo "[Reload] Triggering graceful reload..."
if docker exec "$CONTAINER_NAME" nginx -s reload; then
echo "[Reload] ✅ Reload signal sent successfully."
echo "[Reload] Zero-downtime update in progress."
else
echo "[Reload] ❌ Failed to send reload signal."
exit 1
fi