Initial commit: Traefik v2 con Let's Encrypt y red proxy
This commit is contained in:
8
.env.example
Normal file
8
.env.example
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Email de Let's Encrypt para notificaciones
|
||||||
|
ACME_EMAIL=admin@tudominio.com
|
||||||
|
|
||||||
|
# Dominio para el dashboard (opcional)
|
||||||
|
TRAEFIK_DASHBOARD_DOMAIN=traefik.tudominio.com
|
||||||
|
|
||||||
|
# Zona horaria
|
||||||
|
TZ=Europe/Madrid
|
||||||
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Traefik
|
||||||
|
letsencrypt/
|
||||||
|
acme.json
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
152
README.md
Normal file
152
README.md
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
# Infraestructura: Traefik
|
||||||
|
|
||||||
|
# Traefik v2 — Reverse Proxy con Let's Encrypt
|
||||||
|
|
||||||
|
Este repositorio despliega **Traefik** como proxy inverso con HTTPS automático (Let's Encrypt), listo para servir como puerta de entrada a tus servicios Docker mediante la red compartida `proxy`.
|
||||||
|
|
||||||
|
## ¿Qué es Traefik?
|
||||||
|
|
||||||
|
Traefik es un reverse proxy moderno y ligero que detecta servicios Docker automáticamente y los expone vía HTTP/HTTPS con reglas declarativas (labels) y certificados TLS automáticos con Let's Encrypt.
|
||||||
|
|
||||||
|
## Características
|
||||||
|
|
||||||
|
- 🔒 HTTPS automático con Let's Encrypt (HTTP-01)
|
||||||
|
- 🧠 Descubrimiento automático de servicios Docker
|
||||||
|
- 🧷 Redirección HTTP→HTTPS
|
||||||
|
- 🧰 Dashboard web (seguro por dominio)
|
||||||
|
- 🧩 Middlewares: auth básica, headers de seguridad, rate limit, etc.
|
||||||
|
|
||||||
|
## Requisitos
|
||||||
|
|
||||||
|
- Docker + Docker Compose
|
||||||
|
- Red Docker externa `proxy`
|
||||||
|
- Dominio apuntando al servidor (para dashboard y certificados)
|
||||||
|
- Puertos 80 y 443 accesibles desde Internet
|
||||||
|
|
||||||
|
## Arquitectura
|
||||||
|
|
||||||
|
```
|
||||||
|
Internet → Traefik (80/443) → Servicios (en red proxy)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Despliegue
|
||||||
|
|
||||||
|
### 1) Crear red `proxy`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network create proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Clonar y desplegar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.ictiberia.com/groales/traefik
|
||||||
|
cd traefik
|
||||||
|
|
||||||
|
# Crear carpeta y archivo para ACME
|
||||||
|
mkdir -p letsencrypt
|
||||||
|
# Windows PowerShell
|
||||||
|
echo $null > .\letsencrypt\acme.json
|
||||||
|
# Linux/macOS
|
||||||
|
# touch ./letsencrypt/acme.json
|
||||||
|
|
||||||
|
# Permisos (Linux)
|
||||||
|
# chmod 600 ./letsencrypt/acme.json
|
||||||
|
|
||||||
|
# Desplegar
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Configurar dominio y email
|
||||||
|
|
||||||
|
Edita `traefik.yml` y ajusta:
|
||||||
|
- `certificatesResolvers.letsencrypt.acme.email`
|
||||||
|
- (Opcional) Cambia el dominio del dashboard en labels del contenedor (`traefik.tudominio.com`)
|
||||||
|
|
||||||
|
Reinicia:
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dashboard Seguro
|
||||||
|
|
||||||
|
Este stack expone el dashboard por dominio usando TLS y el servicio interno `api@internal`.
|
||||||
|
|
||||||
|
Para proteger con autenticación básica (opcional):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
labels:
|
||||||
|
- "traefik.http.routers.traefik.middlewares=traefik-auth"
|
||||||
|
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$<hash>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Generar hash (htpasswd):
|
||||||
|
```bash
|
||||||
|
# Linux/macOS
|
||||||
|
htpasswd -nb admin 'TuPassword'
|
||||||
|
|
||||||
|
# PowerShell con OpenSSL (alternativa)
|
||||||
|
# openssl passwd -apr1 TuPassword
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exponer Servicios Detrás de Traefik
|
||||||
|
|
||||||
|
Conecta tus servicios a la red `proxy` y añade labels. Ejemplo: Portainer
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:lts
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.portainer.rule=Host(`portainer.tudominio.com`)"
|
||||||
|
- "traefik.http.routers.portainer.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.portainer.tls=true"
|
||||||
|
- "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
|
||||||
|
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Buenas Prácticas
|
||||||
|
|
||||||
|
- Usa `exposedByDefault=false` (ya configurado) y habilita servicios con `traefik.enable=true`
|
||||||
|
- No expongas puertos directos (`ports:`) si accedes vía Traefik
|
||||||
|
- Protege el dashboard con dominio + auth o restringe por IP
|
||||||
|
- Usa Let's Encrypt staging para pruebas intensivas:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
acme:
|
||||||
|
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- Certificado no se emite:
|
||||||
|
- Verifica DNS y apertura del puerto 80
|
||||||
|
- Revisa logs: `docker logs traefik | Select-String -Pattern cert,acme,error`
|
||||||
|
- 404 en servicio:
|
||||||
|
- Revisa labels y que el contenedor tenga `traefik.enable=true`
|
||||||
|
- Verifica que el servicio está en la red `proxy`
|
||||||
|
- Dashboard no carga:
|
||||||
|
- Asegura que el dominio apunta al servidor
|
||||||
|
- Verifica las labels del router `traefik`
|
||||||
|
|
||||||
|
## Documentación adicional
|
||||||
|
|
||||||
|
Consulta la **Wiki**: https://git.ictiberia.com/groales/traefik/wiki
|
||||||
|
|
||||||
|
- Configuración avanzada (middlewares, serversTransport, mTLS)
|
||||||
|
- Ejemplos por servicio (Jellyfin, Nextcloud, Vaultwarden)
|
||||||
|
- Seguridad (headers, rate limiting, IP whitelist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Última actualización**: Noviembre 2025
|
||||||
32
docker-compose.yaml
Normal file
32
docker-compose.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:latest
|
||||||
|
container_name: traefik
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:80" # HTTP
|
||||||
|
- "443:443" # HTTPS
|
||||||
|
# - "8080:8080" # Dashboard (exponer solo si lo proteges)
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- ./traefik.yml:/traefik.yml:ro
|
||||||
|
- ./letsencrypt:/letsencrypt
|
||||||
|
environment:
|
||||||
|
TZ: "Europe/Madrid"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
# Dashboard seguro por dominio
|
||||||
|
- "traefik.http.routers.traefik.rule=Host(`traefik.tudominio.com`)"
|
||||||
|
- "traefik.http.routers.traefik.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.traefik.tls=true"
|
||||||
|
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.traefik.service=api@internal"
|
||||||
|
# Opcional: Autenticación básica
|
||||||
|
# - "traefik.http.routers.traefik.middlewares=traefik-auth"
|
||||||
|
# - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$..."
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
31
traefik.yml
Normal file
31
traefik.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
insecure: false
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: websecure
|
||||||
|
scheme: https
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
endpoint: "unix:///var/run/docker.sock"
|
||||||
|
exposedByDefault: false
|
||||||
|
network: proxy
|
||||||
|
file:
|
||||||
|
directory: /etc/traefik/dynamic
|
||||||
|
watch: true
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
acme:
|
||||||
|
email: admin@tudominio.com
|
||||||
|
storage: /letsencrypt/acme.json
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: web
|
||||||
Reference in New Issue
Block a user