Integración de DigitalOcean Spaces para Almacenamiento de Objetos

DigitalOcean Spaces es un servicio de almacenamiento de objetos compatible con la API de AWS S3, lo que facilita enormemente su integración con herramientas existentes como rclone, AWS CLI o cualquier SDK compatible con S3. Con un precio fijo de 5$/mes por 250 GB y transferencia incluida, Spaces es una opción muy competitiva para almacenar backups, activos estáticos y archivos multimedia desde tu servidor VPS. Esta guía cubre la configuración del acceso API, la integración con rclone y la automatización de backups.

Requisitos Previos

  • Cuenta de DigitalOcean activa
  • Servidor Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
  • AWS CLI o rclone instalado
  • Acceso root o sudo

Creación del Space y Claves de Acceso

Crear un Space desde la API

# También se puede hacer desde el panel web de DigitalOcean
# En el panel: Spaces > Create a Space

# Alternativa: usar la API de DigitalOcean
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TU_TOKEN_DO" \
  -d '{
    "name": "mi-space-backups",
    "region": "fra1"
  }' \
  "https://api.digitalocean.com/v2/spaces"

Generar las claves de acceso S3

  1. Ve al panel de DigitalOcean: API > Spaces Keys
  2. Haz clic en Generate New Key
  3. Anota el Access Key y el Secret Key (solo se muestran una vez)

Las claves tienen este formato:

  • Endpoint: fra1.digitaloceanspaces.com (varía según la región)
  • Access Key: DO00XXXXXXXXXXXX
  • Secret Key: cadena-de-40-caracteres

Configuración con AWS CLI

La compatibilidad con la API de S3 permite usar AWS CLI directamente con Spaces.

# Configurar un perfil específico para DigitalOcean Spaces
aws configure --profile digitalocean

# Introducir:
# AWS Access Key ID: TU_ACCESS_KEY_DO
# AWS Secret Access Key: TU_SECRET_KEY_DO
# Default region name: fra1
# Default output format: json

# Añadir el endpoint personalizado a la configuración
cat >> ~/.aws/config << 'EOF'

[profile digitalocean]
region = fra1
output = json
s3 =
    endpoint_url = https://fra1.digitaloceanspaces.com
    signature_version = s3v4
EOF

Verificar la conexión

# Listar los Spaces disponibles
aws s3 ls --profile digitalocean --endpoint-url https://fra1.digitaloceanspaces.com

# Listar el contenido de un Space
aws s3 ls s3://mi-space-backups/ \
  --profile digitalocean \
  --endpoint-url https://fra1.digitaloceanspaces.com

# Subir un archivo de prueba
aws s3 cp /etc/hostname s3://mi-space-backups/test.txt \
  --profile digitalocean \
  --endpoint-url https://fra1.digitaloceanspaces.com

Configuración con rclone

rclone es la herramienta más flexible para trabajar con múltiples proveedores de almacenamiento.

# Instalar rclone
curl https://rclone.org/install.sh | sudo bash
rclone --version

Configuración interactiva

rclone config

Selecciona:

  • n - New remote
  • Nombre: do-spaces
  • Tipo: s3 (Amazon S3 Compliant Storage Providers)
  • Provider: DigitalOcean Spaces
  • Access Key ID: TU_ACCESS_KEY_DO
  • Secret Access Key: TU_SECRET_KEY_DO
  • Region: (dejar vacío)
  • Endpoint: fra1.digitaloceanspaces.com
  • Location constraint: (dejar vacío)
  • ACL: private

Configuración manual del archivo rclone

# Crear la configuración directamente en el archivo
mkdir -p ~/.config/rclone/
cat > ~/.config/rclone/rclone.conf << 'EOF'
[do-spaces]
type = s3
provider = DigitalOcean
access_key_id = DO00XXXXXXXXXXXX
secret_access_key = tu_secret_key_aqui
endpoint = fra1.digitaloceanspaces.com
acl = private
EOF

# Verificar la configuración
rclone lsd do-spaces:

Gestión de Archivos

# Listar todos los Spaces
rclone lsd do-spaces:

# Listar archivos en un Space
rclone ls do-spaces:mi-space-backups

# Subir un archivo
rclone copy /var/log/syslog do-spaces:mi-space-backups/logs/

# Subir un directorio completo
rclone copy /var/www/ do-spaces:mi-space-backups/web/

# Sincronizar (solo sube los cambios)
rclone sync /var/www/ do-spaces:mi-space-backups/web/

# Sincronizar con eliminación de archivos borrados en origen
rclone sync /var/www/ do-spaces:mi-space-backups/web/ --delete-during

# Descargar archivos
rclone copy do-spaces:mi-space-backups/web/ /var/www-restaurado/

# Copiar entre Spaces o entre diferentes proveedores
rclone copy do-spaces:mi-space-backups backblaze-b2:mi-bucket-replica

# Ver el tamaño total del Space
rclone size do-spaces:mi-space-backups

# Borrar un archivo
rclone delete do-spaces:mi-space-backups/logs/syslog

# Mover archivos entre carpetas
rclone move do-spaces:mi-space-backups/old/ do-spaces:mi-space-backups/archive/

Opciones avanzadas de rclone

# Transferencias paralelas para mayor velocidad
rclone sync /var/backups/ do-spaces:mi-space-backups/backups/ \
  --transfers 20 \
  --checkers 40 \
  --progress

# Excluir archivos por patrón
rclone sync /var/www/ do-spaces:mi-space-backups/web/ \
  --exclude "*.log" \
  --exclude ".git/**" \
  --exclude "node_modules/**"

# Limitar el ancho de banda
rclone sync /var/www/ do-spaces:mi-space-backups/web/ \
  --bwlimit 10M

# Modo verboso para depuración
rclone sync /var/www/ do-spaces:mi-space-backups/web/ \
  --verbose 2>&1 | tee /var/log/rclone.log

Habilitación del CDN

DigitalOcean Spaces incluye un CDN integrado que sirve los archivos públicos desde puntos de presencia globales.

# Habilitar el CDN mediante la API de DigitalOcean
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TU_TOKEN_DO" \
  -d '{
    "origin": "mi-space-backups.fra1.digitaloceanspaces.com",
    "ttl": 3600
  }' \
  "https://api.digitalocean.com/v2/cdn/endpoints"

# La URL del CDN será del tipo:
# https://mi-space-backups.fra1.cdn.digitaloceanspaces.com/archivo.jpg

Subir archivos como públicos para el CDN

# Hacer un archivo accesible públicamente
aws s3 cp imagen.jpg s3://mi-space-backups/public/imagen.jpg \
  --acl public-read \
  --profile digitalocean \
  --endpoint-url https://fra1.digitaloceanspaces.com

# La URL de acceso directo sería:
# https://mi-space-backups.fra1.digitaloceanspaces.com/public/imagen.jpg
# La URL del CDN sería:
# https://mi-space-backups.fra1.cdn.digitaloceanspaces.com/public/imagen.jpg

Configurar dominio personalizado para el CDN

  1. En el panel de DigitalOcean: Spaces > CDN
  2. Añade el subdominio personalizado (p.ej., cdn.tudominio.com)
  3. En tu DNS (Cloudflare), crea un registro CNAME:
    • cdn.tudominio.commi-space-backups.fra1.cdn.digitaloceanspaces.com

Automatización de Backups

#!/bin/bash
# Script de backup completo a DigitalOcean Spaces
# Guardar en: /usr/local/bin/backup-do-spaces.sh

SPACE="do-spaces:mi-space-backups"
FECHA=$(date +%Y-%m-%d)
LOG="/var/log/backup-spaces.log"

# Función para registrar mensajes
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"
}

log "=== Inicio de backup diario ==="

# Backup de archivos web
log "Sincronizando archivos web..."
rclone sync /var/www/ "$SPACE/web/" \
  --exclude "*.log" \
  --exclude "*.tmp" \
  --exclude "cache/**" \
  --log-file "$LOG" \
  --log-level INFO

# Backup de base de datos MySQL
log "Realizando dump de MySQL..."
mysqldump --all-databases --single-transaction | \
  gzip > "/tmp/mysql-all-$FECHA.sql.gz"

rclone copy "/tmp/mysql-all-$FECHA.sql.gz" "$SPACE/databases/" \
  --log-file "$LOG"

rm -f "/tmp/mysql-all-$FECHA.sql.gz"

# Backup de configuraciones del sistema
log "Copiando configuraciones..."
tar czf "/tmp/etc-backup-$FECHA.tar.gz" /etc/
rclone copy "/tmp/etc-backup-$FECHA.tar.gz" "$SPACE/config/" \
  --log-file "$LOG"
rm -f "/tmp/etc-backup-$FECHA.tar.gz"

# Eliminar backups de configuraciones con más de 30 días
log "Limpiando backups antiguos..."
rclone delete "$SPACE/config/" \
  --min-age 30d \
  --log-file "$LOG"

log "=== Backup completado ==="
# Hacer el script ejecutable
chmod +x /usr/local/bin/backup-do-spaces.sh

# Programar backups diarios a las 3 AM
(crontab -l 2>/dev/null; echo "0 3 * * * /usr/local/bin/backup-do-spaces.sh") | crontab -

Integración con Python

#!/usr/bin/env python3
# Integración de DigitalOcean Spaces con Python via boto3

import boto3
from botocore.config import Config

# Configurar el cliente S3 con el endpoint de Spaces
s3 = boto3.client(
    's3',
    region_name='fra1',
    endpoint_url='https://fra1.digitaloceanspaces.com',
    aws_access_key_id='DO00XXXXXXXXXXXX',
    aws_secret_access_key='tu_secret_key_aqui',
    config=Config(signature_version='s3v4')
)

# Listar archivos en el Space
def listar_archivos(space_name, prefijo=''):
    respuesta = s3.list_objects_v2(Bucket=space_name, Prefix=prefijo)
    archivos = [obj['Key'] for obj in respuesta.get('Contents', [])]
    return archivos

# Subir un archivo
def subir_archivo(ruta_local, space_name, clave_destino):
    s3.upload_file(ruta_local, space_name, clave_destino)
    print(f"Subido: {ruta_local} → {space_name}/{clave_destino}")

# Descargar un archivo
def descargar_archivo(space_name, clave, ruta_local):
    s3.download_file(space_name, clave, ruta_local)
    print(f"Descargado: {space_name}/{clave} → {ruta_local}")

# Ejemplo de uso
if __name__ == '__main__':
    archivos = listar_archivos('mi-space-backups', 'databases/')
    print(f"Archivos encontrados: {len(archivos)}")
    for f in archivos:
        print(f"  - {f}")

Solución de Problemas

Error: SignatureDoesNotMatch

# Verificar que la versión de firma es s3v4
# En la configuración de rclone, la región y el endpoint deben coincidir

# Probar con AWS CLI especificando la versión de firma
aws configure set s3.signature_version s3v4 --profile digitalocean

Error de acceso denegado

# Verificar que las claves tienen los permisos correctos
# Las claves de Spaces se gestionan en: panel DO > API > Spaces Keys
# Cada clave tiene acceso a todos los Spaces de la cuenta

rclone muy lento

# Aumentar las transferencias paralelas
rclone sync /datos/ do-spaces:mi-space/ \
  --transfers 32 \
  --multi-thread-streams 4 \
  --fast-list

Verificar la integridad de los archivos

# Comparar origen y destino
rclone check /var/www/ do-spaces:mi-space-backups/web/ --combined /tmp/diff.txt
cat /tmp/diff.txt

Conclusión

DigitalOcean Spaces ofrece una solución de almacenamiento de objetos sencilla, económica y compatible con S3 que se integra perfectamente con cualquier VPS mediante rclone o AWS CLI. Con el CDN incluido y el precio fijo mensual, es ideal para almacenar backups, activos estáticos y archivos multimedia sin la complejidad de precios variables de otros proveedores cloud.