bolt Valebyte VPS desde $4/mes — NVMe, despliegue en 60s.

Obtener VPS arrow_forward
eco Principiante Tutorial/Cómo hacer

Instalación de SurrealDB en un VPS: Docker, TLS, almacenamiento persistente y copias de seguridad automáticas

calendar_month Oct 30, 2026 schedule 19 min de lectura visibility 16 vistas
Установка SurrealDB на VPS: Docker, TLS, persistent storage и автоматические бэкапы
info

¿Necesitas un servidor para esta guía? Ofrecemos servidores dedicados y VPS en más de 50 países con configuración instantánea.

¿Necesitas un VPS para esta guía?

Explore otras opciones de servidores dedicados en

Instalación de SurrealDB en un VPS: Docker, TLS, almacenamiento persistente y copias de seguridad automáticas

TL;DR

En esta guía desplegaremos SurrealDB 2.x en Ubuntu Server 24.04 mediante Docker Compose, conectaremos un almacenamiento persistente, protegeremos la base de datos detrás de Caddy con TLS automático, configuraremos el firewall y copias de seguridad diarias en S3 mediante Restic.

  • SurrealDB funcionará en un contenedor independiente con una versión de imagen fija.
  • Los datos se almacenarán en el disco del VPS, no dentro del contenedor Docker efímero.
  • Solo quedará público el puerto HTTPS 443; el puerto 8000 de SurrealDB estará disponible únicamente de forma local.
  • Caddy obtendrá y renovará automáticamente el certificado TLS de Let’s Encrypt.
  • Diariamente se crearán una exportación lógica de la base de datos y una copia de seguridad de la configuración.
  • Antes de actualizar, se podrá realizar una comprobación, una exportación manual y revertir el contenedor a la versión anterior.

1. TL;DR

Esta sección ya contiene un plan resumido del despliegue. Si es la primera vez que trabaja con un VPS, ejecute los comandos en orden: primero prepare el sistema operativo, después instale Docker, cree el directorio del proyecto, configure las variables de entorno, inicie los contenedores y solo después conecte el DNS al servidor.

2. Contenido

El artículo está dirigido al propietario de un VPS que quiere ejecutar SurrealDB por su cuenta para una aplicación SaaS, un servicio interno, un prototipo o un pequeño proyecto de producción. La configuración no está vinculada a un framework concreto: es posible conectarse a la base de datos mediante HTTP API, WebSocket o el SDK oficial.

Para producción es importante comprender los límites del ejemplo. Un VPS con una sola copia de la base de datos no es un clúster tolerante a fallos. TLS, el firewall y las copias de seguridad protegen frente a errores operativos habituales, pero no sustituyen a un servidor redundante, la monitorización ni las comprobaciones periódicas de restauración de datos.

3. Qué configuramos y por qué

Qué es SurrealDB

SurrealDB es una base de datos multimodelo compatible con enfoques documental, de grafos y relacional. Proporciona su propio lenguaje similar a SQL, SurrealQL, HTTP API, conexiones WebSocket y un mecanismo de autenticación. Resulta útil cuando la aplicación necesita documentos, relaciones entre entidades y consultas a varios modelos de datos sin un conjunto independiente de servicios especializados.

En la guía se utiliza la rama SurrealDB 2.x. La etiqueta concreta de la imagen debe fijarse, en lugar de utilizar latest. Una actualización impredecible puede cambiar la sintaxis de las consultas, el formato de exportación o el comportamiento de las transacciones durante el reinicio del contenedor.

Arquitectura de la instalación final

En el servidor funcionarán dos contenedores de Docker Compose:

  • surrealdb — servidor de la base de datos, que escucha HTTP y WebSocket en una dirección interna de la red Docker;
  • caddy — reverse proxy, que recibe solicitudes HTTPS y las reenvía a SurrealDB.

El puerto 8000 no se publicará en Internet. Caddy se conectará a SurrealDB mediante el nombre del servicio surrealdb:8000. Los datos de la base se ubicarán en el directorio /srv/surrealdb/data, que se montará en el contenedor. La configuración de Compose, el archivo .env, Caddyfile y la exportación de la base de datos estarán separados de las capas de Docker.

Qué obtendrá después de completar las instrucciones

Después de la configuración tendrá una dirección del tipo https://db.example.com. A través de ella, la aplicación podrá ejecutar solicitudes API a SurrealDB. El servidor obtendrá automáticamente un certificado TLS y Caddy lo renovará sin necesidad de ejecutar Certbot manualmente.

También estará disponible un comando para realizar una comprobación manual:

curl -fsS https://db.example.com/health

Si SurrealDB funciona correctamente, responderá con un estado HTTP exitoso. Para las operaciones administrativas deben utilizarse credenciales independientes y no se debe transmitir la contraseña en la URL, el historial del shell ni el código fuente de la aplicación.

Self-hosted o servicio managed

Criterio SurrealDB en un VPS propio Servicio managed
Control Control total sobre el sistema operativo, la red, las versiones y la ubicación de los datos Parte de la infraestructura está oculta y la gestiona el proveedor
Coste Coste fijo del VPS y del almacenamiento independiente para las copias de seguridad El pago depende del plan, las operaciones, el tráfico y el volumen de datos
Mantenimiento Las actualizaciones, la monitorización y la restauración se realizan de forma autónoma El operador del servicio se encarga de parte de las tareas
Flexibilidad Es posible cambiar las reglas de red, el proxy y la estructura de archivos Solo están disponibles las API y configuraciones previstas

La opción Self-hosted es razonable si los datos deben permanecer en una ubicación elegida, se necesita un presupuesto predecible o se requiere un control total del entorno. Una solución Managed puede ser mejor para un equipo sin experiencia en administración, para sistemas críticos que requieran alta disponibilidad o cuando no haya tiempo para probar personalmente la restauración.

Limitaciones de un servidor único

Un VPS tiene un único punto de fallo: un problema con el disco, el hipervisor, la conectividad de red o un comando incorrecto del administrador puede dejar la base de datos temporalmente inaccesible. Una copia de seguridad en el mismo directorio no protege frente a la pérdida de todo el servidor, por lo que las copias deben enviarse a un almacenamiento externo compatible con S3 o a otro servidor.

No publique SurrealDB directamente en Internet sin TLS y restricciones de red. Incluso con autenticación integrada, un puerto abierto aumenta la superficie de ataque y dificulta el control de acceso.

4. Qué configuración de VPS se necesita para esta tarea

Configuración mínima

Para desarrollo, pruebas y una base de datos pequeña será suficiente un VPS con dos CPU virtuales, 4 GB de RAM y un disco SSD rápido de al menos 40 GB. Para producción es necesario dejar margen para la caché de archivos, Docker, el reverse proxy, las copias de seguridad y los procesos en segundo plano de la aplicación.

Escenario CPU RAM Disco Red
Desarrollo local y demo 2 vCPU 2–4 GB SSD NVMe de 40 GB 100 Mbit/s
Producción pequeña 2–4 vCPU 4–8 GB SSD NVMe de 80–160 GB 100–1000 Mbit/s
Carga media 4–8 vCPU 16–32 GB SSD NVMe de más de 200 GB 1 Gbit/s

Como opción inicial práctica puede contratar un VPS con 4 vCPU, 8 GB de RAM, un SSD NVMe de al menos 100 GB, una dirección IPv4 pública y un puerto de 1 Gbit/s. Este margen permitirá ejecutar la propia base de datos, Caddy, un backend pequeño y un servicio de monitorización sin llevar la memoria al límite.

Cómo calcular el disco

El tamaño del disco debe incluir no solo el volumen actual de datos. Deje al menos entre un 30 y un 40 por ciento de espacio libre para archivos temporales, fragmentación, actualizaciones y exportaciones. Por ejemplo, si la base de datos ocupa 35 GB, un disco de 40 GB es demasiado pequeño: la exportación, los registros y los nuevos registros pueden llenar rápidamente el sistema de archivos.

La exportación lógica puede ocupar temporalmente un tamaño comparable al de la base de datos. Si se planea conservar varias copias locales, será necesario aumentar el tamaño del disco o enviar cada copia inmediatamente a un almacenamiento externo.

Cuándo se necesita un dedicated

Un servidor dedicado tiene sentido si la base de datos utiliza constantemente mucha CPU o RAM, trabaja con decenas o cientos de gigabytes de datos, gestiona un flujo elevado de solicitudes o debe ofrecer un rendimiento predecible sin la influencia de otras máquinas virtuales. Un Dedicated también resulta útil para un nodo grande, análisis y varios servicios que no puedan dividirse entre distintos VPS.

Para una sola instancia pequeña de SurrealDB, un Dedicated suele ser excesivo. Primero mida la carga real: uso medio y máximo de CPU, latencia del disco, número de conexiones, tamaño de la base de datos y frecuencia de las consultas. Pasar a un Dedicated sin métricas a menudo solo aumenta los costes, pero no soluciona los índices incorrectos ni las consultas lentas.

Elección de la ubicación

Ubique el VPS cerca de los usuarios y de la aplicación. Si el backend y SurrealDB se encuentran en la misma ubicación, la latencia entre ellos será menor que al conectarse a través de varias regiones. Para los datos personales, tenga también en cuenta los requisitos legales, los contratos con los clientes y las normas de almacenamiento de datos.

Compruebe si el proveedor proporciona una IPv4 pública o solo IPv6. Para el TLS automático, el dominio debe resolver al servidor y los puertos TCP entrantes 80 y 443 deben estar disponibles desde Internet. Si solo se utiliza IPv6, asegúrese de que los clientes admitan realmente dicha ruta.

5. Preparación del servidor

Condiciones iniciales

El ejemplo está pensado para una Ubuntu Server 24.04 LTS recién instalada con un usuario que tenga acceso temporal mediante SSH. Trabaje con un usuario normal con sudo, no como root. Sustituya admin, la dirección IP y el dominio por sus propios valores.

Desde el ordenador local, cree una clave si aún no dispone de una:

ssh-keygen -t ed25519 -C "admin@vps"

Transfiera la clave pública al servidor:

ssh-copy-id admin@SERVER_IP

Compruebe el acceso mediante la clave en un terminal nuevo. No cierre la sesión SSH actual hasta asegurarse de que el nuevo método de acceso funciona.

Actualización y paquetes básicos

Conéctese al servidor y actualice el índice de paquetes:

sudo apt update
sudo apt full-upgrade -y

Instale las herramientas de diagnóstico, el firewall, la protección de SSH y las utilidades para trabajar con repositorios:

sudo apt install -y \
  ca-certificates \
  curl \
  gnupg \
  lsb-release \
  git \
  jq \
  unzip \
  htop \
  ncdu \
  ufw \
  fail2ban \
  restic

Reinicie el servidor si se actualizó el kernel:

sudo reboot

Usuario y sudo

Si el usuario aún no se ha creado, ejecute el comando como root o como un administrador existente:

sudo adduser deploy
sudo usermod -aG sudo deploy
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo cp /home/admin/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys

Compruebe el acceso:

ssh deploy@SERVER_IP

Configuración de SSH

Cree un archivo drop-in independiente para SSH, para no modificar la configuración principal:

sudo tee /etc/ssh/sshd_config.d/ hardening.conf >/dev/null <<'EOF'

En la ruta anterior no debe haber ningún espacio. Utilice el comando correcto:

sudo tee /etc/ssh/sshd_config.d/hardening.conf >/dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
EOF

sudo sshd -t
sudo systemctl reload ssh

Antes de desactivar las contraseñas, asegúrese de haber comprobado el acceso mediante clave. Si pierde la única clave operativa y desactiva la contraseña, necesitará la consola del proveedor o el modo rescue.

Firewall UFW

Deje abiertos SSH, HTTP y HTTPS. No abra el puerto 8000: solo se utilizará dentro de la red Docker.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Si SSH funciona en un puerto no estándar, sustituya la regla 22/tcp por el puerto real. Si utiliza IPv6, compruebe que las reglas de UFW también se apliquen a IPv6.

Fail2ban

Cree una configuración local de jail para SSH:

sudo tee /etc/fail2ban/jail.d/sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
port = 22
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Fail2ban no sustituye a las claves, el firewall ni las actualizaciones. Solo bloquea temporalmente las direcciones IP desde las que se observan intentos de acceso fallidos repetidos.

6. Instalación del software — paso a paso

6. Instalación del software — paso a paso

Paso 1. Instalación de Docker Engine y Compose Plugin

Para Ubuntu se puede utilizar el script oficial de instalación de Docker. En production es preferible conectar el repositorio apt oficial y fijar las versiones de los paquetes, pero para el primer despliegue el script reduce la cantidad de acciones manuales.

curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sudo sh /tmp/get-docker.sh
rm /tmp/get-docker.sh

Añada el usuario actual al grupo Docker:

sudo usermod -aG docker "$USER"
newgrp docker

Compruebe las versiones:

docker --version
docker compose version
docker run --rm hello-world

En 2026 utilice una versión actual de Docker Engine y Compose v2, pero para garantizar la reproducibilidad fije la versión de la imagen de SurrealDB en el archivo Compose. El grupo Docker proporciona de facto permisos cercanos a los de root, por lo que no añada usuarios innecesarios.

Paso 2. Creación de la estructura de directorios

Cree un directorio independiente para la aplicación, un directorio de datos y un directorio para las exportaciones locales:

sudo mkdir -p /srv/surrealdb/{data,backups,caddy/data,caddy/config}
sudo chown -R "$USER":"$USER" /srv/surrealdb
cd /srv/surrealdb

No elimine el directorio data al reinstalar los contenedores. Allí se encuentran los datos persistentes de SurrealDB.

Paso 3. Creación del archivo de secretos

Docker Compose leerá el archivo .env. La contraseña debe ser larga, aleatoria y única para esta base de datos. No añada el archivo a Git.

DB_ROOT_PASSWORD="$(openssl rand -base64 32 | tr -dc 'A-Za-z0-9_@%+=' | head -c 32)"
printf 'SURREAL_ROOT_USER=root\nSURREAL_ROOT_PASSWORD=%s\n' "$DB_ROOT_PASSWORD" > /srv/surrealdb/.env
chmod 600 /srv/surrealdb/.env
cat /srv/surrealdb/.env

Guarde la contraseña en un gestor de secretos. El comando cat se muestra únicamente para la comprobación inicial y no debe ejecutarse durante la grabación del terminal o la demostración de pantalla.

Paso 4. Creación de Docker Compose

A continuación se utiliza un ejemplo de la imagen surrealdb/surrealdb:v2.6.0. Antes de la instalación, compruebe la disponibilidad de la etiqueta estable necesaria en el registro y elija una versión probada con su aplicación. No sustituya la etiqueta por latest.

cat > /srv/surrealdb/compose.yml <<'EOF'
services:
  surrealdb:
    image: surrealdb/surrealdb:v2.6.0
    container_name: surrealdb
    restart: unless-stopped
    command:
      - start
      - --log
      - info
      - --user
      - ${SURREAL_ROOT_USER}
      - --pass
      - ${SURREAL_ROOT_PASSWORD}
      - rocksdb:/data/database.db
    environment:
      TZ: UTC
    volumes:
      - ./data:/data
    expose:
      - "8000"
    healthcheck:
      test: ["CMD", "/surreal", "isready", "--endpoint", "http://127.0.0.1:8000"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 20s
    networks:
      - surrealnet

  caddy:
    image: caddy:2.10-alpine
    container_name: surrealdb-caddy
    restart: unless-stopped
    depends_on:
      surrealdb:
        condition: service_healthy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/data:/data
      - ./caddy/config:/config
    networks:
      - surrealnet

networks:
  surrealnet:
    driver: bridge
EOF

El comando start inicia el servidor, mientras que la ruta rocksdb:/data/database.db indica a SurrealDB que utilice un archivo RocksDB dentro del directorio persistente. No monte el mismo archivo simultáneamente en varias instancias de la base de datos.

Paso 5. Inicio y comprobación de los contenedores

Antes de iniciar, compruebe la interpolación final de las variables y la sintaxis de Compose:

cd /srv/surrealdb
docker compose --env-file .env config

Inicie los servicios en segundo plano:

docker compose --env-file .env up -d surrealdb

Consulte el estado y los registros:

docker compose ps
docker compose logs --tail=100 surrealdb

En esta etapa Caddy aún no está configurado, por lo que primero compruebe el endpoint interno:

curl -fsS http://127.0.0.1:8000/health || true
docker inspect --format='{{json .State.Health}}' surrealdb | jq

Si el contenedor finaliza, no lo reinicie indefinidamente en un bucle. Primero examine los registros: las causas más frecuentes son una variable de entorno incorrecta, un puerto ocupado, un directorio de datos dañado o un error en los parámetros de inicio.

Paso 6. Comprobación de la versión de la imagen

Asegúrese de que el contenedor se ejecuta con la imagen esperada:

docker inspect --format='{{.Config.Image}}' surrealdb
docker exec surrealdb /surreal version

En production, registre la etiqueta elegida en el registro de cambios del proyecto. Si la aplicación depende de capacidades concretas de SurrealQL, cree un escenario de prueba de migraciones y consultas antes de actualizar.

7. Configuración

DNS y nombre de dominio

Supongamos que la base de datos estará disponible en db.example.com. Cree un registro DNS de tipo A que apunte a la dirección IPv4 del VPS. Si utiliza IPv6, añada un registro AAAA solo después de comprobar el enrutamiento y el firewall.

Puede comprobar el DNS desde el propio servidor:

getent hosts db.example.com
dig +short A db.example.com
dig +short AAAA db.example.com

No active TLS automático hasta que el DNS empiece a devolver la dirección correcta. Let’s Encrypt debe poder conectarse desde el exterior al puerto 80 o 443.

Caddyfile para TLS y reverse proxy

Cree el archivo /srv/surrealdb/Caddyfile. Sustituya el dominio y el email de contacto por sus propios valores:

cat > /srv/surrealdb/Caddyfile <<'EOF'
{
    email [email protected]
}

db.example.com {
    encode zstd gzip

    reverse_proxy surrealdb:8000 {
        health_uri /health
        health_interval 30s
        health_timeout 5s
    }

    log {
        output file /data/access.log
        format json
    }

    header {
        Strict-Transport-Security "max-age=31536000"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "no-referrer"
    }
}
EOF

chmod 644 /srv/surrealdb/Caddyfile

Caddy obtiene el certificado, lo almacena en el directorio caddy/data y lo renueva automáticamente. Este directorio también debe incluirse en las copias de seguridad: sin él, Caddy podrá obtener el certificado de nuevo, pero se perderán los datos locales sobre el estado de ACME y el historial de configuración.

Inicio de Caddy

Después de configurar el DNS, inicie el reverse proxy:

cd /srv/surrealdb
docker compose --env-file .env up -d
docker compose ps
docker compose logs --tail=100 caddy

En los registros debería aparecer un mensaje sobre la emisión correcta del certificado o sobre que el certificado ya existe. Si Caddy no puede obtener el certificado, compruebe el DNS, UFW, el security group del proveedor y la existencia de otro proceso en los puertos 80 o 443.

Comprobación de HTTPS

Compruebe TLS y el endpoint de health:

curl -I https://db.example.com
curl -fsS https://db.example.com/health
openssl s_client -connect db.example.com:443 -servername db.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates

Espere una respuesta HTTP sin errores de certificado y unas fechas de validez del certificado correspondientes al periodo actual. Realice la comprobación desde un equipo externo, no solo desde el propio VPS: la comprobación local puede no detectar problemas de enrutamiento o DNS.

Comprobación de la autenticación

Para la API administrativa, utilice la contraseña del archivo local de secretos. No la pase en la línea de comandos si esto provoca que aparezca en el historial o en la lista de procesos. El endpoint concreto y el formato de la solicitud dependen de la versión de SurrealDB y del SDK utilizado, por lo que debe comparar el ejemplo con la documentación de la versión instalada.

La comprobación mínima de disponibilidad del servidor se realiza sin transmitir el secreto:

curl -fsS https://db.example.com/health

A continuación, ejecute una consulta de prueba desde un script temporal de la aplicación o desde el CLI oficial, pasando las credenciales mediante variables de entorno. Después de la comprobación, elimine los registros de prueba o utilice una base de datos y un namespace independientes.

Comprobación del almacenamiento persistente

Asegúrese de que el directorio de datos está montado:

docker inspect surrealdb --format '{{range .Mounts}}{{println .Source " -> " .Destination}}{{end}}'
sudo du -sh /srv/surrealdb/data
sudo find /srv/surrealdb/data -maxdepth 2 -type f -ls | head

Para comprobar la persistencia tras un reinicio, cree un registro de prueba, reinicie el contenedor y vuelva a leerlo. Hágalo en un namespace de prueba si la base de datos ya está siendo utilizada por la aplicación.

docker compose restart surrealdb
docker compose ps
docker compose logs --tail=50 surrealdb

Configuración de los límites de recursos

Si en el VPS se ejecutan otros servicios, establezca límites razonables para el contenedor. No establezca un límite de memoria inferior al conjunto de trabajo real: si falta memoria, el proceso puede ser finalizado por el OOM-killer.

services:
  surrealdb:
    deploy:
      resources:
        limits:
          cpus: "4.0"
          memory: 6G
        reservations:
          cpus: "1.0"
          memory: 2G

En Docker Compose normal, el campo deploy no es compatible del mismo modo con todos los modos. Antes de aplicarlo, compruebe el resultado con el comando docker inspect. Lo más importante es dejar al sistema operativo un mínimo de 1–2 GB de RAM y supervisar el swap, la latencia del disco y los eventos OOM.

8. Copias de seguridad y mantenimiento

Qué es necesario guardar

La copia de seguridad debe incluir los datos de la base de datos, la configuración de Compose, Caddyfile, el directorio de Caddy con el estado de ACME y el archivo de variables de entorno. La contraseña de .env no debe publicarse en texto plano, por lo que el repositorio de Restic debe estar cifrado y la contraseña de Restic debe almacenarse por separado.

  • /srv/surrealdb/data — archivos persistentes de la base de datos;
  • /srv/surrealdb/compose.yml — descripción de los contenedores;
  • /srv/surrealdb/Caddyfile — reverse proxy y configuración de TLS;
  • /srv/surrealdb/caddy/data y caddy/config — estado de Caddy;
  • exportación lógica de SurrealDB — capa de recuperación independiente del formato de archivos.

No dependa únicamente de copiar el directorio activo de la base de datos. En una base de datos basada en archivos es importante tener en cuenta la coherencia de los datos. La exportación lógica realizada por el propio servidor suele ser más fácil de trasladar entre versiones y almacenamientos.

Preparación de S3 y Restic

Cree un bucket S3 separado con permisos limitados: solo escritura y lectura de los objetos de la copia de seguridad, sin acceso a otros buckets. Configure las variables de Restic en un archivo accesible únicamente para root:

sudo install -m 600 /dev/null /root/restic.env
sudo tee /root/restic.env >/dev/null <<'EOF'
export AWS_ACCESS_KEY_ID='REPLACE_ME'
export AWS_SECRET_ACCESS_KEY='REPLACE_ME'
export RESTIC_REPOSITORY='s3:https://s3.example.net/my-surrealdb-backups'
export RESTIC_PASSWORD='REPLACE_WITH_LONG_RESTIC_PASSWORD'
EOF

No almacene este archivo en un repositorio Git público. Si dispone de un secret manager estándar, es preferible cargar las claves desde allí durante la ejecución de la tarea cron.

Script de copia de seguridad diaria

Cree un directorio para las exportaciones temporales y el script:

sudo mkdir -p /var/lib/surrealdb-backup
sudo tee /usr/local/sbin/backup-surrealdb >/dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail

PROJECT_DIR="/srv/surrealdb"
BACKUP_DIR="/var/lib/surrealdb-backup"
STAMP="$(date -u +%Y-%m-%dT%H-%M-%SZ)"
EXPORT_FILE="${BACKUP_DIR}/surrealdb-${STAMP}.surql"

source /root/restic.env

mkdir -p "$BACKUP_DIR"

cd "$PROJECT_DIR"

docker compose --env-file .env ps --status running surrealdb | grep -q surrealdb

docker exec surrealdb /surreal export \
  --endpoint http://127.0.0.1:8000 \
  --user "$SURREAL_ROOT_USER" \
  --pass "$SURREAL_ROOT_PASSWORD" \
  "$EXPORT_FILE"

restic backup \
  "$EXPORT_FILE" \
  "$PROJECT_DIR/compose.yml" \
  "$PROJECT_DIR/Caddyfile" \
  "$PROJECT_DIR/.env" \
  "$PROJECT_DIR/caddy"

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune

rm -f "$EXPORT_FILE"

echo "Backup completed: $STAMP"
EOF

sudo chmod 700 /usr/local/sbin/backup-surrealdb

En algunas versiones, los parámetros de exportación de CLI pueden variar. Ejecute docker exec surrealdb /surreal export --help y adapte el comando a la versión instalada. Si CLI no puede escribir el archivo en una ruta dentro del contenedor, utilice un directorio temporal con un volume separado o envíe la exportación a stdout redirigiéndola al host.

Inicialización del repositorio y ejecución de prueba

Inicialice el repositorio cifrado de Restic:

sudo bash -c 'source /root/restic.env && restic init'
sudo /usr/local/sbin/backup-surrealdb

Compruebe la lista de snapshots:

sudo bash -c 'source /root/restic.env && restic snapshots'
sudo bash -c 'source /root/restic.env && restic check'

El comando restic check comprueba la estructura del repositorio, pero no demuestra que la aplicación pueda restaurar la base de datos. Como mínimo una vez al mes, realice una restauración de prueba completa en un directorio temporal separado o en un VPS de pruebas.

Programador cron

Cree una tarea diaria que se ejecute, por ejemplo, a las 03:15 UTC:

sudo tee /etc/cron.d/surrealdb-backup >/dev/null <<'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 3    root /usr/local/sbin/backup-surrealdb >> /var/log/surrealdb-backup.log 2>&1
EOF

sudo chmod 644 /etc/cron.d/surrealdb-backup
sudo systemctl restart cron

Configure una notificación de fallos. Una opción sencilla es enviar el estado a un servicio externo de healthcheck al final del script; una opción más fiable es utilizar una herramienta de monitorización que compruebe cuándo apareció el último snapshot de Restic y el tamaño del repositorio.

Restauración de la exportación

Primero descargue el snapshot necesario en un directorio separado:

sudo mkdir -p /var/lib/surrealdb-restore
sudo bash -c 'source /root/restic.env && restic restore latest --target /var/lib/surrealdb-restore'
sudo find /var/lib/surrealdb-restore -type f -name '.surql' -ls

No importe datos sobre la única base de datos de producción sin una ventana de mantenimiento y un plan probado. Inicie un contenedor temporal en un directorio separado, importe la exportación y compruebe el número de registros y las consultas principales de la aplicación. Solo después planifique la restauración de producción.

Actualización de SurrealDB

La actualización debe realizarse durante una maintenance window:

  1. comprobar las release notes y la compatibilidad con SurrealQL;
  2. crear una exportación manual;
  3. comprobar que exista un snapshot reciente de Restic;
  4. cambiar únicamente la etiqueta de la imagen en compose.yml;
  5. iniciar el contenedor y comprobar el health endpoint;
  6. ejecutar las pruebas smoke de la aplicación.
cd /srv/surrealdb
sudo /usr/local/sbin/backup-surrealdb
docker compose pull surrealdb
docker compose up -d surrealdb
docker compose ps
docker compose logs --tail=100 surrealdb
curl -fsS https://db.example.com/health

En una base de datos con una sola instancia esto no es un rolling update: habrá una interrupción breve. Un esquema rolling requiere versiones compatibles, una instancia separada, una replicación bien diseñada y la comprobación del comportamiento de los clientes. No intente obtener una actualización sin interrupciones iniciando simplemente un segundo contenedor en el mismo directorio de datos.

Monitorización

Controle el espacio libre, la memoria, los reinicios del contenedor, los errores en los logs y la latencia del disco:

df -h
free -h
docker stats --no-stream
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
sudo journalctl -u docker --since "1 hour ago"
sudo dmesg -T | grep -i -E 'oom|killed process|ext4|nvme' || true

Conviene activar la alerta del disco cuando el uso alcance entre el 70 y el 80 por ciento, en lugar de esperar al 100 por ciento. Con el disco lleno, la base de datos puede dejar de escribir transacciones, mientras que Caddy y Docker pueden dejar de crear logs y archivos temporales.

9. Troubleshooting y FAQ

¿Por qué el contenedor de SurrealDB se detiene inmediatamente?

Primero ejecute docker compose logs --tail=200 surrealdb y compruebe la configuración final con el comando docker compose config. Las causas frecuentes son un nombre de variable incorrecto, un error en los parámetros de start, un directorio de datos inaccesible o una etiqueta de imagen incompatible. Compruebe también docker exec surrealdb /surreal version si el contenedor alcanza a iniciarse. No elimine el directorio data antes de determinar la causa.

¿Por qué Caddy no obtiene el certificado TLS?

Compruebe que el registro DNS del dominio apunte a este VPS y que los puertos 80 y 443 estén permitidos tanto en UFW como en el security group externo. Ejecute curl -I http://db.example.com desde otra red y consulte docker compose logs caddy. Si Nginx o Apache ya utiliza el puerto, deténgalo o migre el servicio. Compruebe también que el email sea correcto y que no exista un rate limit temporal de ACME.

Obtengo un timeout al conectarme a la base de datos

Asegúrese de que el contenedor esté healthy: docker compose ps y docker inspect surrealdb. Después compruebe la disponibilidad de Caddy mediante curl -v https://db.example.com/health. El puerto 8000 no se publica intencionadamente hacia el exterior, por lo que la conexión directa a SERVER_IP:8000 no debería funcionar. Si las solicitudes desde Caddy no pasan, compruebe el nombre del servicio surrealdb y la red común de Docker en Compose.

¿Qué configuración mínima de VPS es adecuada?

Para desarrollo bastan 2 vCPU, 2–4 GB de RAM y un SSD de al menos 40 GB. Para un sistema de producción pequeño es más seguro comenzar con 2–4 vCPU, 8 GB de RAM y un NVMe de 80–100 GB. La evaluación debe basarse en el tamaño de la base de datos, el número de clientes simultáneos, la complejidad de las consultas y el volumen de la aplicación en el mismo servidor. Mantenga al menos un 30 por ciento del disco libre y no almacene la única copia de seguridad en el mismo VPS.

¿Qué elegir: VPS o dedicated para esta tarea?

Un VPS es adecuado para la mayoría de las instalaciones pequeñas y medianas: es más barato, se escala rápidamente y proporciona suficiente CPU, RAM y SSD. Un dedicated está justificado con una carga alta constante, grandes volúmenes de datos, requisitos de rendimiento estable o cuando vayan a ejecutarse varios servicios que consuman muchos recursos en el servidor. Tome la decisión basándose en métricas, no en el supuesto prestigio del hardware: mida primero la CPU, la RAM, la E/S y las latencias de las consultas.

Los datos desaparecieron después de recrear el contenedor. ¿Qué se hizo mal?

Lo más probable es que el contenedor se iniciara sin bind mount o volume, o que se eliminara el directorio /srv/surrealdb/data. Compruebe la sección volumes en Compose y la salida de docker inspect surrealdb. El comando docker compose down -v puede eliminar volumes con nombre, por lo que no debe utilizarse sin comprender las consecuencias. Si los datos realmente se han perdido, restaure la última exportación lógica o snapshot de Restic en una instancia de prueba.

¿Cómo cambiar la contraseña de root?

No edite la contraseña únicamente en .env sin entender cómo aplica exactamente la versión actual de SurrealDB los parámetros de inicio. Primero cree una copia de seguridad reciente y estudie el procedimiento compatible para cambiar la cuenta en su versión. Después de cambiar el secreto, actualice .env, reinicie el contenedor y compruebe la conexión de la aplicación. Elimine la contraseña antigua del historial del shell, los archivos temporales y los sistemas de monitorización.

¿Se puede abrir el puerto 8000 para conectarse desde la aplicación?

Si la aplicación está en el mismo VPS, conéctela a la red de Docker mediante http://surrealdb:8000. Si el backend funciona en otro servidor, es más seguro utilizar HTTPS a través de Caddy, una private network o una VPN, en lugar de abrir el puerto 8000 a todo Internet. Si es necesario, limite el firewall a la dirección IP concreta de la aplicación y utilice autenticación igualmente. El endpoint público debe tener TLS y monitorización de los intentos de acceso.

¿Por qué no se crea la copia de seguridad?

Ejecute el script manualmente y observe toda la salida. Compruebe el acceso a S3, que el endpoint sea correcto, la presencia de las variables de /root/restic.env y el espacio libre en /var/lib/surrealdb-backup. Después ejecute restic snapshots y restic check. Compruebe por separado el comando de exportación mediante docker exec: los cambios de CLI entre versiones pueden requerir otro orden o nombres de argumentos. En cron, especifique siempre rutas absolutas.

10. Conclusiones y siguientes pasos

Como resultado, SurrealDB funciona en Docker sobre un VPS con disco persistente, HTTPS mediante Caddy, el puerto interno cerrado y una copia de seguridad diaria cifrada en S3. La configuración sigue siendo reproducible: puede trasladarse a un servidor nuevo, restaurar los datos y fijar la versión de la imagen.

A continuación conviene añadir monitorización externa del health endpoint y de la actualidad de las copias de seguridad, probar periódicamente la restauración y optimizar los índices según las consultas reales. A medida que aumente la carga, separe la aplicación, la base de datos y el sistema de copias de seguridad en recursos independientes y, antes de pasar a varias instancias, compruebe primero la compatibilidad de la replicación y el procedimiento de migración.

¿Te fue útil esta guía?

Tus comentarios nos ayudan a mejorar nuestras guías.

Compartir esta publicación:

Envía esta guía a alguien a quien pueda resultarle útil.

Telegram VKVK WhatsApp Facebook LinkedIn XX

instalación de SurrealDB en un VPS: Docker, TLS, almacenamiento persistente y copias de seguridad automáticas
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.