configuracion actual
This commit is contained in:
9
.claude/settings.local.json
Executable file
9
.claude/settings.local.json
Executable file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__context7__get-library-docs"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
22
.env.example
Executable file
22
.env.example
Executable file
@@ -0,0 +1,22 @@
|
||||
# Variables de entorno para Traefik
|
||||
# Copia este archivo a .env y personaliza los valores
|
||||
|
||||
# Configuración general
|
||||
TZ=America/Argentina/Buenos_Aires
|
||||
|
||||
# Email para Let's Encrypt (OBLIGATORIO)
|
||||
ACME_EMAIL=admin@nucleoriofrio.com
|
||||
|
||||
# Dominio para el dashboard
|
||||
DASHBOARD_DOMAIN=traefik.nucleoriofrio.com
|
||||
|
||||
# Contraseña para el dashboard
|
||||
# Genera con: htpasswd -nb admin tu-password
|
||||
# Luego copia el resultado completo aquí
|
||||
DASHBOARD_AUTH=admin:$$apr1$$8evjzEMf$$FfHNgRWn5E9y3W9qZ9Y5z/
|
||||
|
||||
# Red de Traefik
|
||||
TRAEFIK_NETWORK=traefik-network
|
||||
|
||||
# Logging
|
||||
LOG_LEVEL=INFO # DEBUG, INFO, WARN, ERROR
|
||||
28
.gitignore
vendored
Executable file
28
.gitignore
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
# Environment variables
|
||||
.env
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Certificados locales (desarrollo)
|
||||
certs/
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
|
||||
# Backups
|
||||
*.tar.gz
|
||||
*.zip
|
||||
backups/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
353
README.md
Executable file
353
README.md
Executable file
@@ -0,0 +1,353 @@
|
||||
# Traefik Nucleo - Reverse Proxy Configuration
|
||||
|
||||
Configuración de Traefik v3.5 para el servidor Nucleo002.
|
||||
|
||||
## 📁 Estructura del Proyecto
|
||||
|
||||
```
|
||||
traefikNucleo/
|
||||
├── docker-compose.yml # Configuración principal de Traefik
|
||||
├── traefik/
|
||||
│ └── traefik.yml # Configuración estática
|
||||
├── dynamic/
|
||||
│ └── middlewares.yml # Middlewares (security, cors, etc.)
|
||||
├── examples/
|
||||
│ ├── whoami-service.yml # Ejemplo de servicio nuevo
|
||||
│ └── existing-service.yml # Ejemplo para servicios existentes
|
||||
└── README.md # Este archivo
|
||||
```
|
||||
|
||||
## 🚀 Inicio Rápido
|
||||
|
||||
### 1. Configuración inicial
|
||||
|
||||
Antes de iniciar, **DEBES CAMBIAR**:
|
||||
|
||||
1. **Email en `traefik/traefik.yml`** (línea 43):
|
||||
```yaml
|
||||
email: TU-EMAIL@AQUI.com # Para Let's Encrypt
|
||||
```
|
||||
|
||||
2. **Dominio del dashboard en `docker-compose.yml`** (línea 47):
|
||||
```yaml
|
||||
- "traefik.http.routers.dashboard.rule=Host(`traefik.TU-DOMINIO.com`)"
|
||||
```
|
||||
|
||||
3. **Contraseña del dashboard** (línea 54):
|
||||
```bash
|
||||
# Generar hash de contraseña:
|
||||
htpasswd -nb admin tu-password-seguro
|
||||
|
||||
# Reemplazar en docker-compose.yml:
|
||||
- "traefik.http.middlewares.dashboard-auth.basicauth.users=HASH-AQUI"
|
||||
```
|
||||
|
||||
### 2. Iniciar Traefik
|
||||
|
||||
```bash
|
||||
# Desde el directorio traefikNucleo/
|
||||
docker compose up -d
|
||||
|
||||
# Ver logs
|
||||
docker compose logs -f traefik
|
||||
|
||||
# Verificar que está corriendo
|
||||
docker ps | grep traefik
|
||||
```
|
||||
|
||||
### 3. Acceder al Dashboard
|
||||
|
||||
Después de configurar el DNS de tu dominio:
|
||||
|
||||
```
|
||||
https://traefik.TU-DOMINIO.com
|
||||
```
|
||||
|
||||
Usuario: `admin`
|
||||
Password: la que configuraste
|
||||
|
||||
## 📋 Conectar Servicios Existentes a Traefik
|
||||
|
||||
### Opción A: Via labels en docker-compose.yml
|
||||
|
||||
Edita el `docker-compose.yml` de tu servicio y agrega:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
tu-servicio:
|
||||
# ... configuración existente ...
|
||||
|
||||
networks:
|
||||
- tu-red-original
|
||||
- traefik-network # ← AGREGAR ESTO
|
||||
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.NOMBRE.rule=Host(`DOMINIO.com`)"
|
||||
- "traefik.http.routers.NOMBRE.entrypoints=websecure"
|
||||
- "traefik.http.routers.NOMBRE.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.NOMBRE.loadbalancer.server.port=PUERTO"
|
||||
|
||||
networks:
|
||||
traefik-network:
|
||||
external: true
|
||||
```
|
||||
|
||||
Luego:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Opción B: Conectar contenedor corriendo (sin reiniciar)
|
||||
|
||||
```bash
|
||||
# 1. Conectar a la red de Traefik
|
||||
docker network connect traefik-network nombre-del-contenedor
|
||||
|
||||
# 2. Agregar labels dinámicamente
|
||||
docker update \
|
||||
--label traefik.enable=true \
|
||||
--label traefik.http.routers.NOMBRE.rule='Host(`DOMINIO.com`)' \
|
||||
--label traefik.http.routers.NOMBRE.entrypoints=websecure \
|
||||
--label traefik.http.routers.NOMBRE.tls.certresolver=letsencrypt \
|
||||
--label traefik.http.services.NOMBRE.loadbalancer.server.port=PUERTO \
|
||||
nombre-del-contenedor
|
||||
|
||||
# 3. Reiniciar el contenedor para aplicar labels
|
||||
docker restart nombre-del-contenedor
|
||||
```
|
||||
|
||||
## 🔧 Comandos Útiles
|
||||
|
||||
### Gestión de Traefik
|
||||
|
||||
```bash
|
||||
# Ver logs en tiempo real
|
||||
docker compose logs -f traefik
|
||||
|
||||
# Reiniciar Traefik (recargar configuración)
|
||||
docker compose restart traefik
|
||||
|
||||
# Detener Traefik
|
||||
docker compose down
|
||||
|
||||
# Detener y eliminar volúmenes (CUIDADO: borra certificados SSL)
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
### Ver configuración activa
|
||||
|
||||
```bash
|
||||
# Ver todos los routers activos
|
||||
docker exec traefik traefik healthcheck
|
||||
|
||||
# Inspeccionar contenedor de Traefik
|
||||
docker inspect traefik
|
||||
```
|
||||
|
||||
### Gestión de certificados
|
||||
|
||||
```bash
|
||||
# Ver certificados almacenados
|
||||
docker volume inspect traefik-letsencrypt
|
||||
|
||||
# Backup de certificados
|
||||
docker run --rm -v traefik-letsencrypt:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/letsencrypt-backup.tar.gz /data
|
||||
```
|
||||
|
||||
## 🌐 Ejemplos de Servicios
|
||||
|
||||
### Servicio de prueba (whoami)
|
||||
|
||||
```bash
|
||||
cd examples/
|
||||
docker compose -f whoami-service.yml up -d
|
||||
```
|
||||
|
||||
Accede a: `https://whoami.TU-DOMINIO.com`
|
||||
|
||||
### Tus servicios existentes
|
||||
|
||||
Ver archivo `examples/existing-service.yml` para plantilla.
|
||||
|
||||
Servicios actuales que puedes migrar:
|
||||
- ✅ gitea (puerto 3000)
|
||||
- ✅ portainer (puerto 9443)
|
||||
- ✅ authentik (puertos 9100, 9444)
|
||||
- ✅ openwebui (puerto 3020)
|
||||
- ✅ snatchgame-client (puerto 3010)
|
||||
- ✅ planilla-ui (puerto 3008)
|
||||
- Y más...
|
||||
|
||||
## 🔐 SSL/TLS Automático
|
||||
|
||||
Traefik solicita automáticamente certificados SSL de Let's Encrypt cuando:
|
||||
|
||||
1. El dominio apunta a tu IP pública
|
||||
2. Los puertos 80 y 443 están accesibles desde internet
|
||||
3. El contenedor tiene `tls.certresolver=letsencrypt` en sus labels
|
||||
|
||||
### Troubleshooting SSL
|
||||
|
||||
Si los certificados no se generan:
|
||||
|
||||
```bash
|
||||
# Ver logs de ACME (Let's Encrypt)
|
||||
docker compose logs traefik | grep acme
|
||||
|
||||
# Verificar que el dominio apunta a tu IP
|
||||
dig TU-DOMINIO.com
|
||||
|
||||
# Verificar conectividad externa
|
||||
curl -I http://TU-DOMINIO.com
|
||||
```
|
||||
|
||||
## 📊 Middlewares Disponibles
|
||||
|
||||
Los middlewares procesan las peticiones antes de llegar al servicio.
|
||||
|
||||
Usa los middlewares agregándolos a tus labels:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.http.routers.NOMBRE.middlewares=compress,security-headers,rate-limit"
|
||||
```
|
||||
|
||||
### Middlewares configurados:
|
||||
|
||||
- `compress`: Compresión gzip
|
||||
- `security-headers`: Headers de seguridad HTTP
|
||||
- `cors`: Configuración CORS
|
||||
- `rate-limit`: Límite de peticiones (100/s)
|
||||
- `redirect-https`: Redirección forzada a HTTPS
|
||||
- `basic-auth-example`: Autenticación básica
|
||||
- `strip-prefix-api`: Remover `/api` del path
|
||||
|
||||
Ver `dynamic/middlewares.yml` para detalles.
|
||||
|
||||
## 🛠️ Personalización Avanzada
|
||||
|
||||
### Agregar más entry points
|
||||
|
||||
Edita `traefik/traefik.yml`:
|
||||
|
||||
```yaml
|
||||
entryPoints:
|
||||
custom-port:
|
||||
address: ":9000"
|
||||
```
|
||||
|
||||
Expón el puerto en `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "9000:9000"
|
||||
```
|
||||
|
||||
### Configuración TCP/UDP
|
||||
|
||||
Para servicios que no son HTTP (como bases de datos, SSH, etc.):
|
||||
|
||||
Edita `traefik/traefik.yml` y agrega entry points TCP:
|
||||
|
||||
```yaml
|
||||
entryPoints:
|
||||
postgres:
|
||||
address: ":5432"
|
||||
```
|
||||
|
||||
Y configura routers TCP en `dynamic/tcp.yml` (crear archivo nuevo).
|
||||
|
||||
## 📈 Monitoreo
|
||||
|
||||
### Métricas Prometheus
|
||||
|
||||
Traefik expone métricas en:
|
||||
|
||||
```
|
||||
http://IP-SERVIDOR:8082/metrics
|
||||
```
|
||||
|
||||
### Dashboard
|
||||
|
||||
Acceso web completo a:
|
||||
- Routers activos
|
||||
- Services
|
||||
- Middlewares
|
||||
- Certificados TLS
|
||||
- Estadísticas en tiempo real
|
||||
|
||||
## ⚠️ Notas Importantes
|
||||
|
||||
1. **Puertos 80 y 443 deben estar libres** antes de iniciar Traefik
|
||||
2. **Firewall**: Asegúrate de que los puertos están abiertos en tu firewall
|
||||
3. **DNS**: Los dominios deben apuntar a la IP de tu servidor
|
||||
4. **Backup**: Haz backup regular del volumen `traefik-letsencrypt`
|
||||
5. **Let's Encrypt rate limits**: Máximo 5 certificados duplicados por semana
|
||||
|
||||
## 🆘 Solución de Problemas
|
||||
|
||||
### Traefik no inicia
|
||||
|
||||
```bash
|
||||
# Ver logs detallados
|
||||
docker compose logs traefik
|
||||
|
||||
# Verificar puertos ocupados
|
||||
ss -tuln | grep ':80\|:443'
|
||||
|
||||
# Verificar permisos del socket de Docker
|
||||
ls -la /var/run/docker.sock
|
||||
```
|
||||
|
||||
### Servicio no aparece en el dashboard
|
||||
|
||||
```bash
|
||||
# Verificar que el contenedor está en la red correcta
|
||||
docker inspect CONTENEDOR | grep -A 10 Networks
|
||||
|
||||
# Verificar labels
|
||||
docker inspect CONTENEDOR | grep -A 20 Labels
|
||||
|
||||
# Ver logs de Traefik para errores
|
||||
docker compose logs traefik | grep error
|
||||
```
|
||||
|
||||
### Certificado SSL no se genera
|
||||
|
||||
1. Verifica que el dominio resuelve: `dig TU-DOMINIO.com`
|
||||
2. Verifica conectividad: `curl http://TU-DOMINIO.com`
|
||||
3. Revisa logs de ACME: `docker compose logs traefik | grep acme`
|
||||
4. Espera unos minutos (Let's Encrypt puede tardar)
|
||||
|
||||
## 📚 Recursos
|
||||
|
||||
- [Documentación oficial de Traefik](https://doc.traefik.io/traefik/)
|
||||
- [Traefik en GitHub](https://github.com/traefik/traefik)
|
||||
- [Let's Encrypt](https://letsencrypt.org/)
|
||||
|
||||
## 🔄 Migración desde Nginx Proxy Manager
|
||||
|
||||
Si vienes de NPM:
|
||||
|
||||
1. Exporta/documenta tus configuraciones de NPM
|
||||
2. Detén NPM: `docker stop npm npm-db`
|
||||
3. Inicia Traefik: `docker compose up -d`
|
||||
4. Migra servicios uno por uno usando los ejemplos
|
||||
5. Cuando todo funcione, elimina NPM si quieres
|
||||
|
||||
## 🎯 Próximos Pasos
|
||||
|
||||
1. [ ] Cambiar email, dominio y password en la configuración
|
||||
2. [ ] Iniciar Traefik
|
||||
3. [ ] Probar con servicio whoami
|
||||
4. [ ] Migrar un servicio existente
|
||||
5. [ ] Configurar backups de certificados SSL
|
||||
6. [ ] Conectar métricas a Prometheus/Grafana (opcional)
|
||||
|
||||
---
|
||||
|
||||
**Creado para**: Servidor Nucleo002
|
||||
**Fecha**: Octubre 2025
|
||||
**Versión de Traefik**: v3.5
|
||||
76
docker-compose.yml
Executable file
76
docker-compose.yml
Executable file
@@ -0,0 +1,76 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.5
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
|
||||
# Puertos expuestos
|
||||
ports:
|
||||
- "80:80" # HTTP
|
||||
- "443:443" # HTTPS
|
||||
- "8080:8080" # Dashboard (solo si api.insecure=true)
|
||||
- "8082:8082" # Métricas Prometheus
|
||||
|
||||
# Variables de entorno
|
||||
environment:
|
||||
- TZ=America/Argentina/Buenos_Aires
|
||||
- CLOUDFLARE_DNS_API_TOKEN=${CF_API_TOKEN}
|
||||
- CLOUDFLARE_ZONE_API_TOKEN=${CF_API_TOKEN}
|
||||
|
||||
# Volúmenes
|
||||
volumes:
|
||||
# Configuración estática
|
||||
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
|
||||
# Configuración dinámica
|
||||
- ./dynamic:/etc/traefik/dynamic:ro
|
||||
|
||||
# Socket de Docker (para auto-descubrimiento)
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
# Almacenamiento de certificados SSL
|
||||
- traefik-letsencrypt:/letsencrypt
|
||||
|
||||
# Logs
|
||||
- traefik-logs:/var/log/traefik
|
||||
|
||||
# Redes
|
||||
networks:
|
||||
- traefik-network
|
||||
- principal
|
||||
|
||||
# Labels para el dashboard de Traefik
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
# Dashboard en traefik.nucleoriofrio.com
|
||||
- "traefik.http.routers.dashboard.rule=Host(`traefik.nucleoriofrio.com`)"
|
||||
- "traefik.http.routers.dashboard.entrypoints=websecure"
|
||||
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.dashboard.tls.domains[0].main=nucleoriofrio.com"
|
||||
- "traefik.http.routers.dashboard.tls.domains[0].sans=*.nucleoriofrio.com"
|
||||
- "traefik.http.routers.dashboard.service=api@internal"
|
||||
|
||||
# Middleware de autenticación básica para el dashboard
|
||||
- "traefik.http.routers.dashboard.middlewares=dashboard-auth"
|
||||
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$cJ7gew7R$$OtpXnfijB8Nj/XXRp4rHq1"
|
||||
# Usuario: admin, Password: admin (CAMBIAR ESTO!)
|
||||
# Genera tu propio hash con: htpasswd -nb admin tu-password
|
||||
# o en línea: https://hostingcanada.org/htpasswd-generator/
|
||||
|
||||
# Redes
|
||||
networks:
|
||||
traefik-network:
|
||||
name: traefik-network
|
||||
driver: bridge
|
||||
principal:
|
||||
external: true
|
||||
|
||||
# Volúmenes
|
||||
volumes:
|
||||
traefik-letsencrypt:
|
||||
name: traefik-letsencrypt
|
||||
traefik-logs:
|
||||
name: traefik-logs
|
||||
41
dynamic/amigos-nucleoriofrio.yml
Normal file
41
dynamic/amigos-nucleoriofrio.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
# Configuración dinámica para amigos.nucleoriofrio.com
|
||||
# Proxy a amigos-app:3001 con autenticación Authentik
|
||||
|
||||
http:
|
||||
routers:
|
||||
amigos-nucleoriofrio:
|
||||
rule: "Host(`amigos.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: amigos-nucleoriofrio-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authentik-forward-auth
|
||||
- amigos-headers
|
||||
|
||||
services:
|
||||
amigos-nucleoriofrio-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://amigos-app:3001"
|
||||
passHostHeader: true
|
||||
|
||||
middlewares:
|
||||
# Forward Auth con Authentik
|
||||
authentik-forward-auth:
|
||||
forwardAuth:
|
||||
address: "http://authentiknucleo-server-1:9000/outpost.goauthentik.io/auth/traefik"
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- X-authentik-username
|
||||
- X-authentik-email
|
||||
- X-authentik-uid
|
||||
- Set-Cookie
|
||||
|
||||
# Headers personalizados para amigos
|
||||
amigos-headers:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: "https"
|
||||
X-Forwarded-Scheme: "https"
|
||||
30
dynamic/authentik-nucleoriofrio.yml
Normal file
30
dynamic/authentik-nucleoriofrio.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Configuración dinámica para authentik.nucleoriofrio.com
|
||||
# Proxy a authentiknucleo-server-1:9000
|
||||
|
||||
http:
|
||||
routers:
|
||||
authentik-nucleoriofrio:
|
||||
rule: "Host(`authentik.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: authentik-nucleoriofrio-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authentik-headers
|
||||
|
||||
services:
|
||||
authentik-nucleoriofrio-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://authentiknucleo-server-1:9000"
|
||||
passHostHeader: true
|
||||
|
||||
middlewares:
|
||||
authentik-headers:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: "https"
|
||||
X-Forwarded-Scheme: "https"
|
||||
customResponseHeaders:
|
||||
X-Robots-Tag: "noindex, nofollow"
|
||||
17
dynamic/gitea.yml
Normal file
17
dynamic/gitea.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# Configuración de Gitea
|
||||
|
||||
http:
|
||||
routers:
|
||||
gitea:
|
||||
rule: "Host(`gitea.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: gitea-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
|
||||
services:
|
||||
gitea-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://gitea:3000"
|
||||
71
dynamic/middlewares.yml
Executable file
71
dynamic/middlewares.yml
Executable file
@@ -0,0 +1,71 @@
|
||||
# Configuración dinámica - Middlewares
|
||||
# Los middlewares procesan las peticiones antes de llegar al servicio
|
||||
|
||||
http:
|
||||
middlewares:
|
||||
# Middleware para comprimir respuestas
|
||||
compress:
|
||||
compress: {}
|
||||
|
||||
# Middleware para rate limiting (limitar peticiones)
|
||||
rate-limit:
|
||||
rateLimit:
|
||||
average: 100 # 100 peticiones
|
||||
period: 1s # por segundo
|
||||
burst: 50 # permite picos de hasta 50
|
||||
|
||||
# Middleware para headers de seguridad
|
||||
security-headers:
|
||||
headers:
|
||||
frameDeny: true
|
||||
browserXssFilter: true
|
||||
contentTypeNosniff: true
|
||||
forceSTSHeader: true
|
||||
stsIncludeSubdomains: true
|
||||
stsPreload: true
|
||||
stsSeconds: 31536000
|
||||
customResponseHeaders:
|
||||
X-Powered-By: "Nucleo Rio Frio"
|
||||
Server: ""
|
||||
|
||||
# Middleware para CORS
|
||||
cors:
|
||||
headers:
|
||||
accessControlAllowMethods:
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
- DELETE
|
||||
- OPTIONS
|
||||
accessControlAllowOriginList:
|
||||
- "*" # CAMBIAR por tus dominios específicos en producción
|
||||
accessControlAllowHeaders:
|
||||
- "*"
|
||||
accessControlMaxAge: 100
|
||||
addVaryHeader: true
|
||||
|
||||
# Middleware para redirección HTTPS
|
||||
redirect-https:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
||||
# Middleware de autenticación básica de ejemplo
|
||||
# Genera usuarios con: htpasswd -nb usuario password
|
||||
basic-auth-example:
|
||||
basicAuth:
|
||||
users:
|
||||
- "user:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" # user:password
|
||||
realm: "Área Protegida"
|
||||
|
||||
# Middleware para agregar prefijo a las rutas
|
||||
strip-prefix-api:
|
||||
stripPrefix:
|
||||
prefixes:
|
||||
- "/api"
|
||||
|
||||
# Middleware para timeout
|
||||
timeout:
|
||||
forwardAuth:
|
||||
address: "http://localhost"
|
||||
trustForwardHeader: true
|
||||
43
dynamic/musica-nucleoriofrio.yml
Normal file
43
dynamic/musica-nucleoriofrio.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
# Configuración dinámica para musica.nucleoriofrio.com
|
||||
# Proxy a repodructor:3000 (Reproductor de música con Nuxt)
|
||||
|
||||
http:
|
||||
routers:
|
||||
musica-nucleoriofrio:
|
||||
rule: "Host(`musica.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: musica-nucleoriofrio-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- musica-headers
|
||||
- musica-body-size
|
||||
|
||||
services:
|
||||
musica-nucleoriofrio-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://repodructor:3000"
|
||||
passHostHeader: true
|
||||
# Optimizaciones para streaming
|
||||
responseForwarding:
|
||||
flushInterval: "100ms"
|
||||
|
||||
middlewares:
|
||||
# Headers personalizados para el reproductor
|
||||
musica-headers:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: "https"
|
||||
X-Forwarded-Scheme: "https"
|
||||
customResponseHeaders:
|
||||
X-Frame-Options: "SAMEORIGIN"
|
||||
X-Content-Type-Options: "nosniff"
|
||||
X-XSS-Protection: "1; mode=block"
|
||||
Cache-Control: "public, max-age=3600"
|
||||
|
||||
# Tamaño máximo de body para subir archivos
|
||||
musica-body-size:
|
||||
buffering:
|
||||
maxRequestBodyBytes: 104857600 # 100MB
|
||||
23
dynamic/portainer.yml
Normal file
23
dynamic/portainer.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Configuración de Portainer
|
||||
|
||||
http:
|
||||
routers:
|
||||
portainer:
|
||||
rule: "Host(`portainer.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: portainer-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
|
||||
services:
|
||||
portainer-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "https://portainer:9443"
|
||||
serversTransport: portainer-transport
|
||||
|
||||
# Transport para aceptar certificado autofirmado de Portainer
|
||||
serversTransports:
|
||||
portainer-transport:
|
||||
insecureSkipVerify: true
|
||||
45
dynamic/wifi-nucleoriofrio.yml
Normal file
45
dynamic/wifi-nucleoriofrio.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
# Configuración dinámica para wifi.nucleoriofrio.com
|
||||
# Proxy a radiusnucleo-node-1:3000 con soporte SSE y WebSocket
|
||||
|
||||
http:
|
||||
routers:
|
||||
wifi-nucleoriofrio:
|
||||
rule: "Host(`wifi.nucleoriofrio.com`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: wifi-nucleoriofrio-service
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- wifi-headers
|
||||
|
||||
services:
|
||||
wifi-nucleoriofrio-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://radiusnucleo-node-1:3000"
|
||||
# Configuración para Server-Sent Events (SSE)
|
||||
passHostHeader: true
|
||||
responseForwarding:
|
||||
flushInterval: 1ms # Para SSE - envía datos inmediatamente
|
||||
serversTransport: wifi-transport
|
||||
|
||||
# Middleware para headers específicos
|
||||
middlewares:
|
||||
wifi-headers:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: "https"
|
||||
X-Forwarded-Scheme: "https"
|
||||
# No agregar security headers que puedan interferir con SSE
|
||||
|
||||
# Transport específico para SSE y WebSocket
|
||||
serversTransports:
|
||||
wifi-transport:
|
||||
serverName: radiusnucleo-node-1
|
||||
insecureSkipVerify: false
|
||||
# Timeouts largos para SSE
|
||||
forwardingTimeouts:
|
||||
dialTimeout: 30s
|
||||
responseHeaderTimeout: 0s # Sin timeout para headers de respuesta (SSE)
|
||||
idleConnTimeout: 90s
|
||||
52
examples/existing-service.yml
Executable file
52
examples/existing-service.yml
Executable file
@@ -0,0 +1,52 @@
|
||||
# Ejemplo: Conectar un servicio EXISTENTE a Traefik
|
||||
#
|
||||
# IMPORTANTE: Para conectar servicios que ya están corriendo:
|
||||
# 1. Agregar el servicio a la red traefik-network
|
||||
# 2. Agregar los labels de Traefik
|
||||
|
||||
# Opción 1: Conectar la red manualmente
|
||||
# docker network connect traefik-network nombre-del-contenedor
|
||||
|
||||
# Opción 2: Modificar el docker-compose.yml del servicio existente
|
||||
# Ejemplo con tu servicio 'gitea':
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:1.23.7
|
||||
container_name: gitea
|
||||
restart: unless-stopped
|
||||
|
||||
# Agregar la red de Traefik
|
||||
networks:
|
||||
- gitea # Red original del servicio
|
||||
- traefik-network # Red de Traefik
|
||||
|
||||
# Labels para Traefik
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
# Router para el servicio web
|
||||
- "traefik.http.routers.gitea-web.rule=Host(`gitea.nucleoriofrio.com`)"
|
||||
- "traefik.http.routers.gitea-web.entrypoints=websecure"
|
||||
- "traefik.http.routers.gitea-web.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.gitea-web.loadbalancer.server.port=3000"
|
||||
|
||||
# Middlewares opcionales
|
||||
- "traefik.http.routers.gitea-web.middlewares=compress,security-headers"
|
||||
|
||||
# NOTA: Los puertos ya no necesitan exponerse públicamente
|
||||
# Traefik se encarga de enrutar el tráfico
|
||||
# ports:
|
||||
# - "3000:3000" # Ya no es necesario si usas Traefik
|
||||
|
||||
networks:
|
||||
gitea:
|
||||
external: true # Si ya existe
|
||||
traefik-network:
|
||||
external: true
|
||||
|
||||
# IMPORTANTE para servicios con múltiples puertos (como Gitea con SSH):
|
||||
# Si necesitas exponer SSH (puerto 2222), ese puerto SÍ debe estar en ports:
|
||||
# porque Traefik solo maneja HTTP/HTTPS, no TCP arbitrario (a menos que lo configures)
|
||||
35
examples/whoami-service.yml
Executable file
35
examples/whoami-service.yml
Executable file
@@ -0,0 +1,35 @@
|
||||
# Ejemplo: Servicio whoami con Traefik
|
||||
# Este es un servicio de prueba para verificar que Traefik funciona correctamente
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
whoami:
|
||||
image: traefik/whoami
|
||||
container_name: whoami-example
|
||||
restart: unless-stopped
|
||||
|
||||
# IMPORTANTE: Conectar a la red de Traefik
|
||||
networks:
|
||||
- traefik-network
|
||||
|
||||
# Labels para Traefik
|
||||
labels:
|
||||
# Habilitar Traefik para este contenedor
|
||||
- "traefik.enable=true"
|
||||
|
||||
# Definir el router HTTP
|
||||
- "traefik.http.routers.whoami.rule=Host(`whoami.nucleoriofrio.com`)"
|
||||
- "traefik.http.routers.whoami.entrypoints=websecure"
|
||||
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
|
||||
|
||||
# Especificar el puerto del contenedor (si no es obvio)
|
||||
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
||||
|
||||
# Aplicar middlewares (opcional)
|
||||
- "traefik.http.routers.whoami.middlewares=compress,security-headers"
|
||||
|
||||
# Usar la red externa de Traefik
|
||||
networks:
|
||||
traefik-network:
|
||||
external: true
|
||||
150
server-info.sh
Executable file
150
server-info.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "======================================"
|
||||
echo " SERVER INFORMATION FOR TRAEFIK SETUP"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
# Sistema Operativo
|
||||
echo "## SISTEMA OPERATIVO"
|
||||
echo "---"
|
||||
uname -a
|
||||
echo ""
|
||||
if [ -f /etc/os-release ]; then
|
||||
cat /etc/os-release
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Docker
|
||||
echo "## DOCKER"
|
||||
echo "---"
|
||||
if command -v docker &> /dev/null; then
|
||||
echo "Docker instalado: SÍ"
|
||||
docker --version
|
||||
echo ""
|
||||
echo "Docker daemon status:"
|
||||
systemctl is-active docker 2>/dev/null || echo "No se puede verificar status (puede requerir sudo)"
|
||||
echo ""
|
||||
echo "Contenedores corriendo:"
|
||||
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}" 2>/dev/null || echo "No se puede listar (puede requerir sudo)"
|
||||
else
|
||||
echo "Docker instalado: NO"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Docker Compose
|
||||
echo "## DOCKER COMPOSE"
|
||||
echo "---"
|
||||
if command -v docker-compose &> /dev/null; then
|
||||
echo "Docker Compose instalado: SÍ"
|
||||
docker-compose --version
|
||||
elif docker compose version &> /dev/null; then
|
||||
echo "Docker Compose (plugin) instalado: SÍ"
|
||||
docker compose version
|
||||
else
|
||||
echo "Docker Compose instalado: NO"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Puertos ocupados
|
||||
echo "## PUERTOS CRÍTICOS"
|
||||
echo "---"
|
||||
echo "Verificando puertos 80, 443, 8080..."
|
||||
for port in 80 443 8080; do
|
||||
if command -v ss &> /dev/null; then
|
||||
result=$(ss -tuln | grep ":$port " 2>/dev/null)
|
||||
else
|
||||
result=$(netstat -tuln 2>/dev/null | grep ":$port ")
|
||||
fi
|
||||
|
||||
if [ -n "$result" ]; then
|
||||
echo "Puerto $port: OCUPADO"
|
||||
echo "$result"
|
||||
else
|
||||
echo "Puerto $port: LIBRE"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Servicios web corriendo
|
||||
echo "## SERVICIOS WEB DETECTADOS"
|
||||
echo "---"
|
||||
if command -v systemctl &> /dev/null; then
|
||||
for service in nginx apache2 httpd caddy; do
|
||||
if systemctl list-unit-files | grep -q "^$service.service"; then
|
||||
status=$(systemctl is-active $service 2>/dev/null)
|
||||
echo "$service: $status"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "systemctl no disponible"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Recursos del servidor
|
||||
echo "## RECURSOS DEL SERVIDOR"
|
||||
echo "---"
|
||||
echo "CPU:"
|
||||
grep -m1 "model name" /proc/cpuinfo 2>/dev/null || echo "No disponible"
|
||||
echo "Cores: $(nproc 2>/dev/null || echo 'N/A')"
|
||||
echo ""
|
||||
echo "Memoria:"
|
||||
free -h 2>/dev/null || echo "No disponible"
|
||||
echo ""
|
||||
echo "Disco:"
|
||||
df -h / 2>/dev/null || echo "No disponible"
|
||||
echo ""
|
||||
|
||||
# Networking
|
||||
echo "## NETWORKING"
|
||||
echo "---"
|
||||
echo "IPs del servidor:"
|
||||
if command -v ip &> /dev/null; then
|
||||
ip -4 addr show | grep inet | awk '{print $2}' | grep -v "127.0.0.1"
|
||||
else
|
||||
ifconfig 2>/dev/null | grep "inet " | awk '{print $2}' | grep -v "127.0.0.1"
|
||||
fi
|
||||
echo ""
|
||||
echo "Hostname:"
|
||||
hostname
|
||||
echo ""
|
||||
|
||||
# Dominios/DNS
|
||||
echo "## DOMINIOS CONFIGURADOS (si existen)"
|
||||
echo "---"
|
||||
if [ -f /etc/hosts ]; then
|
||||
echo "Entradas relevantes en /etc/hosts:"
|
||||
grep -v "^#" /etc/hosts | grep -v "127.0.0.1.*localhost" | grep -v "::1" | grep -v "^$"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Docker networks
|
||||
echo "## DOCKER NETWORKS"
|
||||
echo "---"
|
||||
if command -v docker &> /dev/null; then
|
||||
docker network ls 2>/dev/null || echo "No se puede listar (puede requerir sudo)"
|
||||
else
|
||||
echo "Docker no disponible"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Directorio actual y permisos
|
||||
echo "## INFORMACIÓN DEL DIRECTORIO"
|
||||
echo "---"
|
||||
echo "Directorio actual: $(pwd)"
|
||||
echo "Usuario actual: $(whoami)"
|
||||
echo "Permisos:"
|
||||
ls -la $(pwd) 2>/dev/null | head -10
|
||||
echo ""
|
||||
|
||||
# Variables de entorno relevantes
|
||||
echo "## VARIABLES DE ENTORNO RELEVANTES"
|
||||
echo "---"
|
||||
echo "HOME: $HOME"
|
||||
echo "USER: $USER"
|
||||
echo "PATH: $PATH"
|
||||
echo ""
|
||||
|
||||
echo "======================================"
|
||||
echo " FIN DEL REPORTE"
|
||||
echo "======================================"
|
||||
81
traefik/traefik.yml
Executable file
81
traefik/traefik.yml
Executable file
@@ -0,0 +1,81 @@
|
||||
# Configuración estática de Traefik
|
||||
# Este archivo se carga al iniciar Traefik y define la configuración base
|
||||
|
||||
# API y Dashboard
|
||||
api:
|
||||
dashboard: true # Habilita el dashboard web
|
||||
insecure: false # Requiere autenticación (configurada en dynamic/)
|
||||
|
||||
# Entry Points - Puntos de entrada para el tráfico
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
# Redirección automática HTTP -> HTTPS
|
||||
http:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: websecure
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
||||
websecure:
|
||||
address: ":443"
|
||||
http:
|
||||
tls:
|
||||
certResolver: letsencrypt # Usa Let's Encrypt para SSL
|
||||
|
||||
# Entry point para métricas (opcional)
|
||||
metrics:
|
||||
address: ":8082"
|
||||
|
||||
# Providers - De dónde Traefik obtiene su configuración
|
||||
providers:
|
||||
# Docker provider - Auto-descubre contenedores
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
exposedByDefault: false # Solo expone contenedores con labels específicas
|
||||
network: traefik-network # Red Docker para Traefik
|
||||
watch: true # Detecta cambios en tiempo real
|
||||
|
||||
# File provider - Configuraciones dinámicas desde archivos
|
||||
file:
|
||||
directory: /etc/traefik/dynamic
|
||||
watch: true # Recarga automáticamente si hay cambios
|
||||
|
||||
# Certificados SSL automáticos con Let's Encrypt
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: jodarioel87@gmail.com # Email para notificaciones de Let's Encrypt
|
||||
storage: /letsencrypt/acme.json
|
||||
# DNS Challenge para certificados wildcard
|
||||
dnsChallenge:
|
||||
provider: cloudflare
|
||||
resolvers:
|
||||
- "1.1.1.1:53"
|
||||
- "1.0.0.1:53"
|
||||
delayBeforeCheck: 10s
|
||||
|
||||
# Logging
|
||||
log:
|
||||
level: INFO # DEBUG, INFO, WARN, ERROR
|
||||
filePath: /var/log/traefik/traefik.log
|
||||
format: json
|
||||
|
||||
# Access logs
|
||||
accessLog:
|
||||
filePath: /var/log/traefik/access.log
|
||||
format: json
|
||||
bufferingSize: 100
|
||||
|
||||
# Métricas (opcional - para Prometheus)
|
||||
metrics:
|
||||
prometheus:
|
||||
addEntryPointsLabels: true
|
||||
addServicesLabels: true
|
||||
entryPoint: metrics
|
||||
|
||||
# Configuración global
|
||||
global:
|
||||
checkNewVersion: true
|
||||
sendAnonymousUsage: false
|
||||
Reference in New Issue
Block a user