Eliminar página de Backup
520
Backup.md
520
Backup.md
@@ -1,520 +0,0 @@
|
|||||||
# 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)
|
|
||||||
1
Home.md
1
Home.md
@@ -77,7 +77,6 @@ https://<IP-del-servidor>:9443
|
|||||||
|
|
||||||
## Próximos Pasos
|
## Próximos Pasos
|
||||||
|
|
||||||
- 💾 [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
|
- 🌐 [Integración con Traefik](Traefik) - Configurar proxy inverso con TLS automático
|
||||||
- 🔌 [Edge Agents](Edge-Agents) - Gestionar entornos remotos con agentes Edge
|
- 🔌 [Edge Agents](Edge-Agents) - Gestionar entornos remotos con agentes Edge
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user