Documentación completa del wiki en español

2025-11-29 13:39:12 +01:00
commit 7a8c098ac4
5 changed files with 1821 additions and 0 deletions

520
Backup.md Normal file

@@ -0,0 +1,520 @@
# Backup y Restauración
Esta guía explica cómo realizar copias de seguridad y restaurar los datos de Portainer CE.
## ¿Qué se Respalda?
Portainer almacena todos sus datos en el volumen Docker **`portainer_data`**, que incluye:
- 🔐 **Configuración de usuarios y autenticación**
- 🌐 **Entornos (endpoints) configurados**
- 📦 **Stacks, plantillas y configuraciones**
- 🔑 **Secretos, configs, y credenciales**
- 📊 **Configuraciones de roles y permisos**
- 🎨 **Personalizaciones de UI y configuraciones**
⚠️ **Importante**: El volumen `portainer_data` contiene información sensible. Protege los backups adecuadamente.
## Estrategias de Backup
### Opción 1: Backup Manual del Volumen
#### Crear Backup
```bash
# Detener Portainer (recomendado para consistencia)
docker compose down
# Crear backup del volumen usando contenedor temporal
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine \
tar czf /backup/portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
# Reiniciar Portainer
docker compose up -d
```
**Resultado**: Archivo `portainer-backup-YYYYMMDD-HHMMSS.tar.gz` en el directorio actual.
#### Backup sin Detener Portainer (En Caliente)
```bash
# Crear backup sin detener el servicio
docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf /backup/portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
```
⚠️ **Nota**: Los backups en caliente pueden tener inconsistencias si hay cambios durante la copia. Para backups críticos, detén Portainer primero.
#### Restaurar Backup
```bash
# 1. Detener Portainer
docker compose down
# 2. Eliminar volumen existente (⚠️ cuidado!)
docker volume rm portainer_data
# 3. Crear nuevo volumen
docker volume create portainer_data
# 4. Restaurar datos desde backup
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/portainer-backup-YYYYMMDD-HHMMSS.tar.gz -C /data
# 5. Verificar permisos
docker run --rm \
-v portainer_data:/data \
alpine \
chown -R root:root /data
# 6. Reiniciar Portainer
docker compose up -d
```
### Opción 2: Backup con Script Automatizado
Crear script `backup-portainer.sh`:
```bash
#!/bin/bash
# Configuración
BACKUP_DIR="/var/backups/portainer"
RETENTION_DAYS=30
VOLUME_NAME="portainer_data"
COMPOSE_PATH="/ruta/a/tu/portainer"
# Crear directorio de backups si no existe
mkdir -p "$BACKUP_DIR"
# Timestamp
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/portainer-backup-$TIMESTAMP.tar.gz"
echo "[$(date)] Iniciando backup de Portainer..."
# Opción 1: Backup en caliente (servicio corriendo)
docker run --rm \
-v "$VOLUME_NAME":/data:ro \
-v "$BACKUP_DIR":/backup \
alpine \
tar czf "/backup/portainer-backup-$TIMESTAMP.tar.gz" -C /data .
# Opción 2: Backup con detención (más seguro, comentar la opción 1 si usas esta)
# cd "$COMPOSE_PATH"
# docker compose down
# docker run --rm \
# -v "$VOLUME_NAME":/data \
# -v "$BACKUP_DIR":/backup \
# alpine \
# tar czf "/backup/portainer-backup-$TIMESTAMP.tar.gz" -C /data .
# docker compose up -d
# Verificar que el backup se creó
if [ -f "$BACKUP_FILE" ]; then
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "[$(date)] Backup completado: $BACKUP_FILE ($SIZE)"
else
echo "[$(date)] ERROR: Backup falló"
exit 1
fi
# Limpiar backups antiguos
echo "[$(date)] Limpiando backups antiguos (>$RETENTION_DAYS días)..."
find "$BACKUP_DIR" -name "portainer-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "[$(date)] Proceso completado"
```
Hacer ejecutable y probar:
```bash
chmod +x backup-portainer.sh
./backup-portainer.sh
```
### Opción 3: Backup Automatizado con Cron
Programar backups diarios a las 2:00 AM:
```bash
# Editar crontab
crontab -e
# Añadir línea:
0 2 * * * /ruta/a/backup-portainer.sh >> /var/log/portainer-backup.log 2>&1
```
Verificar cron:
```bash
# Ver crontab actual
crontab -l
# Ver logs de backup
tail -f /var/log/portainer-backup.log
```
### Opción 4: Backup a Almacenamiento Remoto
#### Backup a NFS/CIFS
```bash
# Montar share remoto
mount -t nfs servidor.local:/backups /mnt/backups
# Crear backup directamente en share
docker run --rm \
-v portainer_data:/data:ro \
-v /mnt/backups:/backup \
alpine \
tar czf /backup/portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
```
#### Backup a S3/MinIO
Usando `rclone`:
```bash
# Configurar rclone primero
rclone config
# Crear backup y subir a S3
BACKUP_FILE="portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf "/backup/$BACKUP_FILE" -C /data .
rclone copy "$BACKUP_FILE" s3-remote:bucket-name/portainer-backups/
rm "$BACKUP_FILE"
```
#### Backup con rsync
```bash
# Crear backup local
BACKUP_FILE="portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf "/backup/$BACKUP_FILE" -C /data .
# Copiar a servidor remoto
rsync -avz --progress "$BACKUP_FILE" usuario@servidor-backup:/backups/portainer/
# Opcional: eliminar backup local
rm "$BACKUP_FILE"
```
## Restauración de Emergencia
### Escenario 1: Corrupción de Datos
```bash
# 1. Detener Portainer inmediatamente
docker compose down
# 2. Renombrar volumen corrupto (por si acaso)
docker volume create portainer_data_corrupted
docker run --rm \
-v portainer_data:/source \
-v portainer_data_corrupted:/dest \
alpine \
sh -c "cp -a /source/. /dest/"
# 3. Limpiar volumen original
docker volume rm portainer_data
docker volume create portainer_data
# 4. Restaurar desde último backup válido
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/portainer-backup-YYYYMMDD-HHMMSS.tar.gz -C /data
# 5. Reiniciar
docker compose up -d
```
### Escenario 2: Migración a Nuevo Servidor
En el **servidor antiguo**:
```bash
# Crear backup
docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf /backup/portainer-migration.tar.gz -C /data .
# Copiar a nuevo servidor
scp portainer-migration.tar.gz usuario@nuevo-servidor:/tmp/
```
En el **servidor nuevo**:
```bash
# 1. Clonar repositorio o copiar docker-compose.yaml
git clone https://git.ictiberia.com/groales/portainer
cd portainer
# 2. Crear volumen
docker volume create portainer_data
# 3. Restaurar datos
docker run --rm \
-v portainer_data:/data \
-v /tmp:/backup \
alpine \
tar xzf /backup/portainer-migration.tar.gz -C /data
# 4. Iniciar Portainer
docker compose up -d
# 5. Verificar
docker logs portainer
```
### Escenario 3: Rollback a Versión Anterior
Si una actualización de Portainer causa problemas:
```bash
# 1. Detener versión actual
docker compose down
# 2. Editar docker-compose.yaml y cambiar tag
# De: portainer/portainer-ce:lts
# A: portainer/portainer-ce:2.19.4 (versión específica)
# 3. Restaurar backup de antes de la actualización
docker volume rm portainer_data
docker volume create portainer_data
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/portainer-backup-pre-update.tar.gz -C /data
# 4. Iniciar versión anterior
docker compose up -d
```
## Verificación de Backups
### Test de Restauración
Es crítico **probar tus backups regularmente**:
```bash
# 1. Crear volumen de test
docker volume create portainer_data_test
# 2. Restaurar backup en volumen de test
docker run --rm \
-v portainer_data_test:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/portainer-backup-YYYYMMDD-HHMMSS.tar.gz -C /data
# 3. Iniciar Portainer temporal en otro puerto
docker run -d \
-p 19443:9443 \
--name portainer-test \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data_test:/data \
portainer/portainer-ce:lts
# 4. Verificar en https://localhost:19443
# Login y verificar que los datos son correctos
# 5. Limpiar
docker stop portainer-test
docker rm portainer-test
docker volume rm portainer_data_test
```
### Validar Integridad de Backup
```bash
# Verificar que el tar.gz no está corrupto
tar tzf portainer-backup-YYYYMMDD-HHMMSS.tar.gz > /dev/null
echo $? # Debe devolver 0 si OK
# Ver contenido del backup
tar tzf portainer-backup-YYYYMMDD-HHMMSS.tar.gz | head -20
# Ver tamaño
du -h portainer-backup-YYYYMMDD-HHMMSS.tar.gz
```
## Best Practices
### 1. Estrategia 3-2-1
-**3 copias** de tus datos (original + 2 backups)
-**2 medios diferentes** (ej: disco local + NAS)
-**1 copia offsite** (ej: cloud, otro datacenter)
### 2. Frecuencia de Backups
Según criticidad:
| Entorno | Frecuencia Recomendada |
|---------|------------------------|
| Producción crítica | Cada 6-12 horas |
| Producción estándar | Diario |
| Desarrollo/Testing | Semanal |
### 3. Retención
Ejemplo de política:
- **Diarios**: 7 días
- **Semanales**: 4 semanas
- **Mensuales**: 12 meses
- **Anuales**: 3 años
Script de retención:
```bash
# Diarios (últimos 7)
find /backups -name "portainer-backup-*.tar.gz" -mtime +7 -mtime -30 -delete
# Mantener un backup semanal (domingos)
# Mantener un backup mensual (día 1)
# (implementar lógica adicional según necesidades)
```
### 4. Encriptación de Backups
Para backups con datos sensibles:
```bash
# Crear backup encriptado con GPG
BACKUP_FILE="portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf "/backup/$BACKUP_FILE" -C /data .
# Encriptar
gpg --symmetric --cipher-algo AES256 "$BACKUP_FILE"
# Resultado: portainer-backup-YYYYMMDD-HHMMSS.tar.gz.gpg
rm "$BACKUP_FILE" # Eliminar versión sin encriptar
```
Restaurar encriptado:
```bash
# Desencriptar
gpg --decrypt portainer-backup-YYYYMMDD-HHMMSS.tar.gz.gpg > portainer-backup.tar.gz
# Restaurar normalmente
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine \
tar xzf /backup/portainer-backup.tar.gz -C /data
```
### 5. Monitorización de Backups
Script con notificaciones:
```bash
#!/bin/bash
# backup-portainer-monitored.sh
BACKUP_DIR="/var/backups/portainer"
WEBHOOK_URL="https://hooks.slack.com/services/TU_WEBHOOK" # O email, etc.
# ... (lógica de backup) ...
# Notificar resultado
if [ $? -eq 0 ]; then
curl -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "{\"text\":\"✅ Backup Portainer completado: $BACKUP_FILE\"}"
else
curl -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "{\"text\":\"❌ ERROR: Backup Portainer falló\"}"
fi
```
## Troubleshooting
### Error: "Permission denied"
```bash
# Ejecutar backup con sudo
sudo docker run --rm \
-v portainer_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar czf /backup/portainer-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
```
### Backup Muy Grande
```bash
# Ver tamaño del volumen
docker run --rm \
-v portainer_data:/data \
alpine \
du -sh /data
# Limpiar logs/cache dentro del volumen si es necesario
docker run --rm \
-v portainer_data:/data \
alpine \
sh -c "find /data -name '*.log' -delete"
```
### Restauración No Funciona
```bash
# Verificar contenido del backup
tar tzf portainer-backup-YYYYMMDD-HHMMSS.tar.gz | less
# Listar contenido del volumen restaurado
docker run --rm \
-v portainer_data:/data \
alpine \
ls -laR /data
# Verificar permisos
docker run --rm \
-v portainer_data:/data \
alpine \
chown -R root:root /data
```
---
**Recursos adicionales**:
- [Documentación oficial de Portainer](https://docs.portainer.io/)
- [Docker Volume Backup Strategies](https://docs.docker.com/storage/volumes/)
**Volver a**: [Página Principal](Home) | [Instalación Avanzada](Instalacion)

385
Edge-Agents.md Normal file

@@ -0,0 +1,385 @@
# Edge Agents
Los **Edge Agents** permiten gestionar entornos Docker remotos que no tienen conectividad directa bidireccional con Portainer Server. Son ideales para:
- Hosts detrás de firewalls o NAT
- Dispositivos IoT en ubicaciones remotas
- Entornos edge computing
- Sitios con conectividad limitada o intermitente
## ¿Cómo Funcionan?
A diferencia del Portainer Agent estándar (que requiere puerto 9001 accesible), el Edge Agent:
1. **Inicia la conexión** hacia Portainer Server (puerto 8000)
2. **Mantiene un túnel** para comunicación bidireccional
3. **Polling periódico** cuando la conexión se pierde
4. **Modo async** para operaciones cuando está offline
## Requisitos
### En Portainer Server
- ✅ Puerto **8000** expuesto y accesible desde Internet/red remota
- ✅ Dominio o IP pública (recomendado)
- ✅ Certificado SSL válido (recomendado para producción)
### En el Host Remoto
- ✅ Docker instalado
- ✅ Conectividad saliente a Portainer Server (puerto 8000)
- ✅ NO requiere puertos abiertos hacia el host remoto
## Habilitar Edge en Portainer Server
### 1. Exponer Puerto 8000
Edita `docker-compose.yaml` y descomenta el puerto 8000:
```yaml
services:
portainer:
container_name: portainer
image: portainer/portainer-ce:lts
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
ports:
- "9443:9443"
- "8000:8000" # ← Descomentar para Edge Agents
networks:
- portainer_network
```
### 2. Reiniciar Portainer
```bash
docker compose down
docker compose up -d
```
### 3. Verificar Puerto
```bash
# Verificar que el puerto está escuchando
sudo netstat -tulpn | grep :8000
# o con ss
ss -tulpn | grep :8000
```
### 4. Configurar Firewall
```bash
# UFW (Ubuntu/Debian)
sudo ufw allow 8000/tcp
# firewall-cmd (RHEL/CentOS/Fedora)
sudo firewall-cmd --permanent --add-port=8000/tcp
sudo firewall-cmd --reload
# iptables
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
```
## Desplegar Edge Agent en Host Remoto
### Desde la Interfaz de Portainer
1. **Ir a Environments**:
- Click en **Environments** en el menú lateral
- Click en **Add environment**
2. **Seleccionar Tipo**:
- Selecciona **Docker Standalone**
- Click en **Start Wizard**
3. **Elegir Edge Agent**:
- Selecciona la opción **Edge Agent**
- Elige tu sistema operativo (Linux / Windows WSL / Windows WCS)
4. **Configurar Opciones**:
- **Name**: Nombre descriptivo del entorno (ej: `produccion-server1`)
- **Portainer server URL**: `https://portainer.tudominio.com` o `https://IP:9443`
- **Edge ID**: Se genera automáticamente
- **Polling interval**: Frecuencia de sincronización (por defecto 5 segundos)
5. **Copiar Comando**:
Portainer generará un comando similar a este:
**Linux / WSL**:
```bash
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-v /:/host \
-v portainer_agent_data:/data \
--restart always \
-e EDGE=1 \
-e EDGE_ID=<tu-edge-id> \
-e EDGE_KEY=<tu-edge-key> \
-e EDGE_INSECURE_POLL=0 \
--name portainer_edge_agent \
portainer/agent:latest
```
**Windows WCS**:
```powershell
docker run -d `
-v \\.\pipe\docker_engine:\\.\pipe\docker_engine `
-v portainer_agent_data:C:\ProgramData\Portainer `
--restart always `
-e EDGE=1 `
-e EDGE_ID=<tu-edge-id> `
-e EDGE_KEY=<tu-edge-key> `
--name portainer_edge_agent `
portainer/agent:latest
```
6. **Ejecutar en Host Remoto**:
- Conéctate por SSH al host remoto
- Pega y ejecuta el comando
- Espera a que el contenedor se descargue e inicie
### Verificar Conexión
En el host remoto:
```bash
# Ver logs del Edge Agent
docker logs portainer_edge_agent
# Deberías ver mensajes como:
# [INFO] Edge agent started
# [INFO] Polling Portainer server
# [INFO] Successfully connected to Portainer server
```
En Portainer Server:
1. Ve a **Environments**
2. El nuevo entorno debería aparecer con estado **Connected** (punto verde)
3. Click en el entorno para gestionarlo
## Configuración Avanzada
### Intervalo de Polling Personalizado
```bash
docker run -d \
# ... resto de opciones ...
-e EDGE_POLL_INTERVAL=10s \ # Cambiar intervalo (default: 5s)
portainer/agent:latest
```
⚠️ **Nota**: Intervalos muy cortos aumentan el tráfico de red.
### Edge Agent con Host Management
Para habilitar funciones de gestión del host (CPU, memoria, procesos):
```bash
docker run -d \
# ... resto de opciones ...
-v /:/host \ # Montar filesystem del host
portainer/agent:latest
```
### Modo Inseguro (Solo para Desarrollo)
Si usas certificados autofirmados o HTTP:
```bash
docker run -d \
# ... resto de opciones ...
-e EDGE_INSECURE_POLL=1 \ # ⚠️ NO usar en producción
portainer/agent:latest
```
### Edge Agent con Docker Compose
Crear `docker-compose.yaml` en el host remoto:
```yaml
version: '3.8'
services:
portainer_edge_agent:
image: portainer/agent:latest
container_name: portainer_edge_agent
restart: always
environment:
EDGE: "1"
EDGE_ID: "<tu-edge-id>"
EDGE_KEY: "<tu-edge-key>"
EDGE_INSECURE_POLL: "0"
EDGE_POLL_INTERVAL: "5s"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
- /:/host
- portainer_agent_data:/data
volumes:
portainer_agent_data:
```
Desplegar:
```bash
docker compose up -d
```
## Edge Groups y Tags
### Crear Edge Group
Los Edge Groups permiten agrupar múltiples entornos edge para gestión centralizada:
1. **Ir a Edge Groups**:
- Menú lateral → **Edge Groups**
- Click **Add edge group**
2. **Configurar Grupo**:
- **Name**: Nombre del grupo (ej: `iot-devices`)
- **Endpoints**: Seleccionar entornos edge a incluir
- **Tags**: Opcional, para filtrado avanzado
3. **Deploy Stack a Grupo**:
- Puedes desplegar stacks en todos los entornos del grupo simultáneamente
- Los cambios se sincronizan automáticamente
## Edge Stacks
Los **Edge Stacks** son stacks Docker Compose que se despliegan en múltiples entornos edge:
1. **Crear Edge Stack**:
- **Edge Compute** → **Edge Stacks** → **Add stack**
2. **Configurar Stack**:
- **Name**: Nombre del stack
- **Edge groups**: Seleccionar grupos target
- **Compose file**: Pegar tu docker-compose.yaml
3. **Deployment type**:
- **Static**: Se despliega una vez
- **Git**: Se sincroniza desde un repo Git
4. **Pre-pull images**: Descargar imágenes antes de desplegar (recomendado)
## Edge Jobs
Ejecutar comandos en múltiples entornos edge:
1. **Crear Edge Job**:
- **Edge Compute** → **Edge Jobs** → **Add edge job**
2. **Opciones**:
- **Basic**: Comando simple
- **Advanced**: Scripts complejos
3. **Scheduling**:
- **One-off**: Se ejecuta una vez
- **Recurring**: Programado (cron-like)
Ejemplo:
```bash
# Actualizar todos los contenedores en entornos edge
docker compose pull
docker compose up -d
```
## Troubleshooting
### Edge Agent No Conecta
1. **Verificar firewall en servidor**:
```bash
sudo ufw status | grep 8000
```
2. **Verificar puerto 8000 accesible**:
Desde el host remoto:
```bash
telnet <portainer-server-ip> 8000
# o
nc -zv <portainer-server-ip> 8000
```
3. **Revisar logs**:
```bash
docker logs portainer_edge_agent --tail 50
```
### Certificado SSL Inválido
Si usas certificados autofirmados, usa `EDGE_INSECURE_POLL=1` (solo desarrollo):
```bash
docker run -d \
# ... resto de opciones ...
-e EDGE_INSECURE_POLL=1 \
portainer/agent:latest
```
### Edge Agent Se Desconecta Frecuentemente
1. **Aumentar timeout**:
```bash
-e EDGE_POLL_TIMEOUT=30s
```
2. **Verificar estabilidad de red**:
```bash
ping -c 100 <portainer-server-ip>
```
3. **Revisar recursos del host**:
```bash
docker stats portainer_edge_agent
```
### Actualizar Edge Agent
```bash
# Detener y eliminar contenedor actual
docker stop portainer_edge_agent
docker rm portainer_edge_agent
# Pull nueva imagen
docker pull portainer/agent:latest
# Re-ejecutar comando de despliegue con las mismas variables EDGE_ID y EDGE_KEY
```
⚠️ **Importante**: No cambies `EDGE_ID` o `EDGE_KEY`, o necesitarás re-agregar el entorno en Portainer.
## Seguridad
### Recomendaciones
1. ✅ **Usar HTTPS** con certificados válidos
2. ✅ **NO usar** `EDGE_INSECURE_POLL=1` en producción
3.**Limitar acceso** al puerto 8000 con firewall
4.**Rotar Edge Keys** periódicamente (re-deploy agent)
5.**Monitorizar logs** de conexiones sospechosas
### Exponer Solo con VPN (Alternativa Segura)
Si no quieres exponer el puerto 8000 a Internet:
1. **Configurar VPN** (WireGuard, OpenVPN, Tailscale)
2. **Conectar hosts remotos** a la VPN
3. **Configurar Portainer Server URL** con IP privada de VPN
4. **Edge Agents** conectan a través del túnel VPN
---
**Recursos adicionales**:
- [Documentación oficial Edge Compute](https://docs.portainer.io/admin/edge-compute)
- [Edge Agent en GitHub](https://github.com/portainer/agent)
**Volver a**: [Página Principal](Home) | [Instalación Avanzada](Instalacion)

104
Home.md Normal file

@@ -0,0 +1,104 @@
# Portainer CE - Documentación
Bienvenido a la documentación del despliegue de **Portainer Community Edition** usando Docker Compose.
## ¿Qué es Portainer?
Portainer es una plataforma de gestión de contenedores ligera y fácil de usar que te permite administrar tus entornos Docker, Kubernetes, y más a través de una interfaz web intuitiva.
## Componentes del Stack
Este repositorio despliega **Portainer Server** con la siguiente configuración:
### Servicio Principal
- **Imagen**: `portainer/portainer-ce:lts`
- **Contenedor**: `portainer`
- **Reinicio**: Automático (`always`)
### Puertos Expuestos
- **9443**: Interfaz web HTTPS de Portainer (obligatorio)
- **8000**: Túnel TCP para Edge Agents (opcional, no incluido por defecto)
### Volúmenes
- `/var/run/docker.sock:/var/run/docker.sock` - Socket Docker para gestión del host
- `portainer_data:/data` - Almacenamiento persistente de configuración y datos
### Red
- `portainer_network` - Red dedicada para el stack
## Requisitos Previos
Antes de desplegar Portainer, asegúrate de tener:
- ✅ Docker Engine instalado (versión compatible según [requisitos oficiales](https://docs.portainer.io/start/requirements-and-prerequisites))
- ✅ Docker Compose instalado
- ✅ Usuario con permisos para acceder a `/var/run/docker.sock`
- ✅ Puertos 9443 (y opcionalmente 8000) disponibles
- ✅ SELinux deshabilitado (Linux) o usar flag `--privileged` si es necesario
## Despliegue Rápido
### 1. Clonar el Repositorio
```bash
git clone https://git.ictiberia.com/groales/portainer
cd portainer
```
### 2. Revisar Configuración (Opcional)
Edita `docker-compose.yaml` si necesitas personalizar puertos, redes o volúmenes.
### 3. Levantar el Stack
```bash
docker compose up -d
```
### 4. Verificar el Estado
```bash
docker ps --filter name=portainer
```
Deberías ver el contenedor `portainer` en estado `Up`.
### 5. Acceder a la Interfaz Web
Abre tu navegador en:
```
https://<IP-del-servidor>:9443
```
🔐 **Primera vez**: Portainer te pedirá crear un usuario administrador.
⚠️ **Certificado SSL**: Por defecto, Portainer usa un certificado autofirmado. Tu navegador mostrará una advertencia de seguridad. Para producción, configura certificados válidos (ver [Configuración SSL](#)).
## Próximos Pasos
- 📖 [Instalación Avanzada](Instalacion) - Configuración de TLS, variables de entorno y opciones avanzadas
- 💾 [Backup y Restauración](Backup) - Cómo respaldar y restaurar datos de Portainer
- 🌐 [Integración con Traefik](Traefik) - Configurar proxy inverso con TLS automático
- 🔌 [Edge Agents](Edge-Agents) - Gestionar entornos remotos con agentes Edge
## Solución Rápida de Problemas
| Problema | Solución |
|----------|----------|
| Puerto 9443 ocupado | Cambia el puerto en `docker-compose.yaml`: `- "XXXX:9443"` |
| Contenedor no arranca | Revisa logs: `docker logs portainer` |
| No se puede conectar | Verifica firewall y que Docker esté corriendo |
| Error de permisos socket | Añade tu usuario al grupo `docker`: `sudo usermod -aG docker $USER` |
## Recursos Oficiales
- 📘 [Documentación Oficial](https://docs.portainer.io/)
- 🏠 [Sitio Web Portainer](https://www.portainer.io/)
- 💬 [Comunidad](https://www.portainer.io/community)
- 🐛 [Reportar Issues](https://github.com/portainer/portainer/issues)
---
**Versión**: Portainer CE LTS
**Última actualización**: Noviembre 2025

263
Instalacion.md Normal file

@@ -0,0 +1,263 @@
# Instalación Avanzada
Esta página cubre opciones avanzadas de instalación y configuración para Portainer CE.
## Configuración con Variables de Entorno
Puedes usar un archivo `.env` para gestionar variables de configuración. Crea el archivo en la raíz del proyecto:
```bash
# .env
PORTAINER_HTTPS_PORT=9443
PORTAINER_EDGE_PORT=8000
PORTAINER_DATA_VOLUME=portainer_data
PORTAINER_NETWORK=portainer_network
```
Luego referencia estas variables en `docker-compose.yaml`:
```yaml
services:
portainer:
container_name: portainer
image: portainer/portainer-ce:lts
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${PORTAINER_DATA_VOLUME:-portainer_data}:/data
ports:
- "${PORTAINER_HTTPS_PORT:-9443}:9443"
# - "${PORTAINER_EDGE_PORT:-8000}:8000" # Descomenta para Edge Agents
networks:
- ${PORTAINER_NETWORK:-portainer_network}
```
## Configuración de Certificados SSL/TLS
### Opción 1: Certificado Autofirmado (Por Defecto)
Portainer genera automáticamente un certificado autofirmado al iniciar. No requiere configuración adicional, pero los navegadores mostrarán advertencias de seguridad.
### Opción 2: Certificados Propios
Para usar tus propios certificados SSL:
1. **Prepara tus certificados**:
- `cert.pem` - Certificado público
- `key.pem` - Clave privada
2. **Crea una carpeta para certificados**:
```bash
mkdir -p ./certs
cp /ruta/a/tu/cert.pem ./certs/
cp /ruta/a/tu/key.pem ./certs/
chmod 600 ./certs/*.pem
```
3. **Modifica docker-compose.yaml**:
```yaml
services:
portainer:
# ... configuración existente ...
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
- ./certs:/certs:ro
command: --sslcert /certs/cert.pem --sslkey /certs/key.pem
```
4. **Reinicia Portainer**:
```bash
docker compose down
docker compose up -d
```
### Opción 3: Proxy Inverso con Let's Encrypt
La forma más profesional es usar un proxy inverso como Traefik o Nginx con certificados Let's Encrypt. Ver [Integración con Traefik](Traefik).
## Habilitar Edge Agents
Los Edge Agents permiten gestionar entornos Docker remotos que no tienen conectividad directa con Portainer Server.
### 1. Exponer Puerto 8000
Edita `docker-compose.yaml` y descomenta la línea del puerto 8000:
```yaml
ports:
- "9443:9443"
- "8000:8000" # ← Descomentar esta línea
```
### 2. Configurar Firewall
Asegúrate de que el puerto 8000 esté accesible desde tus agentes remotos:
```bash
# Ejemplo con UFW (Ubuntu)
sudo ufw allow 8000/tcp
# Ejemplo con firewall-cmd (RHEL/CentOS)
sudo firewall-cmd --permanent --add-port=8000/tcp
sudo firewall-cmd --reload
```
### 3. Desplegar Edge Agent
Desde la interfaz de Portainer:
1. Ve a **Environments** → **Add environment**
2. Selecciona **Docker Standalone**
3. Elige **Edge Agent**
4. Copia el comando de instalación y ejecútalo en el host remoto
📖 Más información: [Documentación oficial de Edge Agents](https://docs.portainer.io/admin/environments/add/docker/edge)
## Configuración de SELinux
Si usas SELinux en Linux, necesitas ejecutar Portainer con el flag `--privileged`:
```yaml
services:
portainer:
# ... configuración existente ...
privileged: true
```
O configurar políticas SELinux específicas (recomendado para producción):
```bash
sudo semanage fcontext -a -t svirt_sandbox_file_t "/var/lib/docker/volumes/portainer_data(/.*)?"
sudo restorecon -R /var/lib/docker/volumes/portainer_data
```
## Docker Rootless
Portainer puede ejecutarse con Docker rootless, pero con algunas limitaciones:
1. **Montar socket rootless**:
```yaml
volumes:
- $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock
```
2. **Limitaciones conocidas**:
- No se puede gestionar el host (stats, eventos del sistema)
- Algunas funciones de networking pueden no funcionar
- Host management features deshabilitadas
📖 Más información: [Docker Rootless](https://docs.docker.com/engine/security/rootless/)
## Despliegue con Docker Run
Si prefieres no usar Docker Compose:
```bash
# Crear volumen
docker volume create portainer_data
# Ejecutar Portainer
docker run -d \
-p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:lts
```
## Configuración de Red Avanzada
### Usar Red Externa
Si ya tienes una red Docker existente:
```yaml
networks:
portainer_network:
external: true
name: mi_red_existente
```
### IPv6
Para habilitar IPv6:
```yaml
networks:
portainer_network:
enable_ipv6: true
ipam:
config:
- subnet: "fd00::/64"
```
## Limitar Recursos
Para limitar CPU y memoria de Portainer:
```yaml
services:
portainer:
# ... configuración existente ...
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
```
## Configuración de Logging
Personalizar el driver de logs:
```yaml
services:
portainer:
# ... configuración existente ...
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
```
## Troubleshooting Avanzado
### Logs Detallados
Habilitar modo debug:
```yaml
services:
portainer:
# ... configuración existente ...
command: --log-level=DEBUG
```
### Verificar Conectividad al Socket Docker
```bash
# Desde dentro del contenedor
docker exec -it portainer ls -la /var/run/docker.sock
# Verificar permisos
docker exec -it portainer stat -c '%a %U:%G' /var/run/docker.sock
```
### Reset de Admin Password
Si olvidaste la contraseña del admin:
```bash
docker stop portainer
docker run --rm -v portainer_data:/data portainer/helper-reset-password
docker start portainer
```
---
**Próximos pasos**: [Backup y Restauración](Backup) | [Integración con Traefik](Traefik)

549
Traefik.md Normal file

@@ -0,0 +1,549 @@
# Integración con Traefik
Esta guía explica cómo integrar Portainer CE con **Traefik** como proxy inverso para obtener:
- 🔒 **Certificados SSL/TLS automáticos** con Let's Encrypt
- 🌐 **Acceso mediante dominio** en lugar de IP:puerto
- 🔐 **Capa adicional de seguridad** con middlewares
- 📊 **Balanceo de carga** (si usas múltiples instancias)
## Requisitos Previos
- ✅ Traefik instalado y funcionando
- ✅ Red Docker compartida entre Traefik y Portainer
- ✅ Dominio apuntando a tu servidor (para Let's Encrypt)
- ✅ Puertos 80 y 443 accesibles desde Internet (para validación de Let's Encrypt)
## Arquitectura
```
Internet → Traefik (80/443) → Portainer (9443)
Let's Encrypt
```
Traefik gestiona:
- Terminación SSL/TLS
- Renovación automática de certificados
- Redirección HTTP → HTTPS
- Headers de seguridad
## Configuración Básica
### 1. Crear Red Compartida
Si no existe, crear una red para que Traefik y Portainer se comuniquen:
```bash
docker network create traefik_network
```
### 2. Modificar docker-compose.yaml de Portainer
Opción recomendada: usar `docker-compose.override.yaml` (ver abajo).
O editar directamente `docker-compose.yaml`:
```yaml
services:
portainer:
container_name: portainer
image: portainer/portainer-ce:lts
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
# NO exponer puertos directamente
# ports:
# - "9443:9443"
networks:
- portainer_network
- traefik_network # Añadir red de Traefik
labels:
# Habilitar Traefik
- "traefik.enable=true"
# Router HTTP (redirección a HTTPS)
- "traefik.http.routers.portainer-http.rule=Host(`portainer.tudominio.com`)"
- "traefik.http.routers.portainer-http.entrypoints=web"
- "traefik.http.routers.portainer-http.middlewares=redirect-to-https"
# Router HTTPS
- "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"
# Service
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
# Middleware de redirección
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
volumes:
portainer_data:
name: portainer_data
networks:
portainer_network:
name: portainer_network
traefik_network:
external: true
```
### 3. Usar docker-compose.override.yaml (Recomendado)
En el repositorio ya existe `docker-compose.override.yaml.example`. Copiarlo:
```bash
cp docker-compose.override.yaml.example docker-compose.override.yaml
```
Editar `docker-compose.override.yaml`:
```yaml
services:
portainer:
networks:
- traefik_network
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer-http.rule=Host(`portainer.tudominio.com`)"
- "traefik.http.routers.portainer-http.entrypoints=web"
- "traefik.http.routers.portainer-http.middlewares=redirect-to-https"
- "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"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
networks:
traefik_network:
external: true
```
**Ventaja**: El `docker-compose.yaml` base permanece sin cambios, y los overrides se aplican automáticamente.
### 4. Reiniciar Portainer
```bash
docker compose down
docker compose up -d
```
### 5. Verificar
```bash
# Ver logs de Traefik
docker logs traefik
# Verificar que Portainer está en la red de Traefik
docker network inspect traefik_network
```
Acceder a: `https://portainer.tudominio.com`
## Configuración de Traefik
### traefik.yml Mínimo
Si aún no tienes Traefik configurado, aquí un ejemplo básico:
```yaml
# traefik.yml
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: traefik_network
certificatesResolvers:
letsencrypt:
acme:
email: admin@tudominio.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
```
### docker-compose.yml de Traefik
```yaml
version: '3.8'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: always
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard (proteger en producción)
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./letsencrypt:/letsencrypt
networks:
- traefik_network
labels:
# Dashboard (opcional, configurar autenticación)
- "traefik.enable=true"
- "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"
networks:
traefik_network:
external: true
```
Iniciar Traefik:
```bash
docker network create traefik_network
mkdir letsencrypt
touch letsencrypt/acme.json
chmod 600 letsencrypt/acme.json
docker compose up -d
```
## Configuración Avanzada
### Autenticación Básica (Opcional)
Proteger Portainer con autenticación HTTP básica:
```bash
# Generar password hash
echo $(htpasswd -nb admin tu_password) | sed -e s/\\$/\\$\\$/g
# Resultado: admin:$$apr1$$...
```
Añadir labels:
```yaml
labels:
# ... labels existentes ...
- "traefik.http.routers.portainer.middlewares=portainer-auth"
- "traefik.http.middlewares.portainer-auth.basicauth.users=admin:$$apr1$$..."
```
### Headers de Seguridad
```yaml
labels:
# ... labels existentes ...
- "traefik.http.routers.portainer.middlewares=security-headers"
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.stsPreload=true"
- "traefik.http.middlewares.security-headers.headers.forceSTSHeader=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
```
### Rate Limiting
Limitar peticiones para prevenir abusos:
```yaml
labels:
# ... labels existentes ...
- "traefik.http.routers.portainer.middlewares=rate-limit"
- "traefik.http.middlewares.rate-limit.ratelimit.average=100"
- "traefik.http.middlewares.rate-limit.ratelimit.burst=50"
```
### IP Whitelist
Restringir acceso solo desde IPs específicas:
```yaml
labels:
# ... labels existentes ...
- "traefik.http.routers.portainer.middlewares=ip-whitelist"
- "traefik.http.middlewares.ip-whitelist.ipwhitelist.sourcerange=192.168.1.0/24,10.0.0.0/8"
```
### Múltiples Dominios
Acceder a Portainer desde varios dominios:
```yaml
labels:
- "traefik.http.routers.portainer.rule=Host(`portainer.tudominio.com`) || Host(`docker.tudominio.com`)"
```
### Configuración con Subdirectorio
Acceder en `https://tudominio.com/portainer`:
```yaml
labels:
- "traefik.http.routers.portainer.rule=Host(`tudominio.com`) && PathPrefix(`/portainer`)"
- "traefik.http.routers.portainer.middlewares=portainer-stripprefix"
- "traefik.http.middlewares.portainer-stripprefix.stripprefix.prefixes=/portainer"
```
⚠️ **Nota**: Portainer puede tener problemas con subdirectorios. Recomendamos usar subdominios.
## Wildcard Certificates
Para certificados wildcard con DNS challenge:
```yaml
# traefik.yml
certificatesResolvers:
letsencrypt:
acme:
email: admin@tudominio.com
storage: /letsencrypt/acme.json
dnsChallenge:
provider: cloudflare # O tu proveedor DNS
delayBeforeCheck: 30
```
Variables de entorno para Cloudflare:
```yaml
# docker-compose.yml de Traefik
services:
traefik:
environment:
- CF_API_EMAIL=tu@email.com
- CF_API_KEY=tu_api_key
```
Labels en Portainer:
```yaml
labels:
- "traefik.http.routers.portainer.tls.domains[0].main=tudominio.com"
- "traefik.http.routers.portainer.tls.domains[0].sans=*.tudominio.com"
```
## Docker Compose Completo
### Portainer con Traefik
Archivo completo `docker-compose.override.yaml`:
```yaml
version: '3.8'
services:
portainer:
networks:
- traefik_network
labels:
# Habilitar Traefik
- "traefik.enable=true"
# Dominio
- "traefik.http.routers.portainer.rule=Host(`portainer.tudominio.com`)"
# Entrypoints
- "traefik.http.routers.portainer.entrypoints=websecure"
# TLS
- "traefik.http.routers.portainer.tls=true"
- "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
# Service backend
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
# Middlewares (opcional)
- "traefik.http.routers.portainer.middlewares=security-headers"
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
networks:
traefik_network:
external: true
```
## Troubleshooting
### Certificado No Se Genera
1. **Verificar logs de Traefik**:
```bash
docker logs traefik | grep -i error
```
2. **Revisar permisos de acme.json**:
```bash
chmod 600 letsencrypt/acme.json
```
3. **Verificar DNS**:
```bash
nslookup portainer.tudominio.com
dig portainer.tudominio.com
```
4. **Rate limits de Let's Encrypt**:
- Máximo 5 certificados por semana por dominio
- Usar staging durante pruebas:
```yaml
certificatesResolvers:
letsencrypt:
acme:
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
```
### Error 502 Bad Gateway
1. **Verificar que Portainer está corriendo**:
```bash
docker ps | grep portainer
```
2. **Verificar red compartida**:
```bash
docker network inspect traefik_network | grep portainer
```
3. **Revisar puerto del servicio**:
```yaml
# Asegurarse de usar el puerto interno correcto
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
```
4. **Verificar scheme HTTPS**:
```yaml
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
```
### Redirección Infinita
Si hay loop de redirecciones:
```yaml
labels:
# Remover redirección HTTP si Traefik ya lo maneja globalmente
# Comentar estas líneas:
# - "traefik.http.routers.portainer-http.rule=..."
# - "traefik.http.routers.portainer-http.middlewares=redirect-to-https"
```
### Certificado Autofirmado Aún Se Muestra
Portainer usa su propio certificado SSL. Traefik termina SSL antes de llegar a Portainer, por lo que:
1. **Es normal** que Portainer siga usando su cert autofirmado internamente
2. El usuario final ve el certificado de Let's Encrypt de Traefik
3. Traefik se comunica con Portainer por HTTPS (con cert autofirmado)
Si quieres evitar warnings en logs de Traefik:
```yaml
labels:
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
- "traefik.http.services.portainer.loadbalancer.serversTransport=ignorecert"
# En traefik.yml:
# http:
# serversTransports:
# ignorecert:
# insecureSkipVerify: true
```
## Monitorización
### Logs de Traefik
```bash
# Ver requests a Portainer
docker logs -f traefik | grep portainer
# Ver errores TLS
docker logs traefik | grep -i "tls\|certificate"
```
### Verificar Certificado SSL
```bash
# Ver información del certificado
echo | openssl s_client -servername portainer.tudominio.com -connect localhost:443 2>/dev/null | openssl x509 -noout -dates
# Verificar desde exterior
curl -vI https://portainer.tudominio.com 2>&1 | grep -i "SSL\|certificate"
```
## Seguridad Adicional
### 1. Fail2ban con Traefik
Proteger contra brute-force:
```bash
# /etc/fail2ban/filter.d/traefik-auth.conf
[Definition]
failregex = ^<HOST> - - .* "(GET|POST|HEAD).*HTTP.*" 401 .*$
ignoreregex =
```
```ini
# /etc/fail2ban/jail.local
[traefik-auth]
enabled = true
port = http,https
logpath = /var/log/traefik/access.log
maxretry = 5
bantime = 3600
```
### 2. Autenticación de Dos Factores
Portainer tiene 2FA integrado (no depende de Traefik):
1. **Settings****Authentication**
2. Habilitar **OAuth** o **LDAP** con 2FA
3. O usar middleware de Traefik con OAuth2 Proxy
### 3. VPN como Alternativa
Para máxima seguridad, no exponer Portainer a Internet:
1. Acceso solo via VPN (WireGuard, OpenVPN)
2. Traefik escucha solo en IP privada
3. Usuarios conectan primero a VPN
---
**Recursos adicionales**:
- [Documentación Traefik](https://doc.traefik.io/traefik/)
- [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits/)
- [Traefik Middlewares](https://doc.traefik.io/traefik/middlewares/overview/)
**Volver a**: [Página Principal](Home) | [Instalación Avanzada](Instalacion)