SSD Nodes Learn 8GB de RAM — $66/año
Guías Matt ConnorPor Matt Connor · Actualizado 2026-08-02

Instalar Actual Budget en un VPS con Docker

Instala Actual Budget en tu VPS con Docker Compose: volumen de datos, HTTPS obligatorio para el navegador, primer presupuesto, importaciones bancarias y copias de seguridad.

Qué va a configurar

Actual Budget es una aplicación de presupuestos basada en sobres que se aloja en el propio servidor. Es la respuesta habitual cuando se busca una alternativa a YNAB que pueda alojarse de forma autónoma. El servidor consta de un contenedor, un volumen de datos y un nombre HTTPS. Todo lo necesario para un presupuesto normal funciona correctamente en el VPS más pequeño que pueda alquilar, porque el servidor principalmente almacena archivos y los sincroniza.

Conviene comprender la arquitectura antes de escribir cualquier comando. El presupuesto en sí es una base de datos SQLite que reside en el navegador y en cada aplicación móvil. El servidor que va a instalar es un endpoint de sincronización: mantiene la lista de cuentas, los archivos de presupuesto y el registro de cambios que permite que un teléfono y un portátil coincidan. Por eso la aplicación sigue funcionando cuando el servidor está inactivo. También por eso perder el servidor no implica perder el presupuesto, siempre que un cliente conserve una copia.

Por qué el servidor necesita HTTPS

Actual requiere HTTPS, y no es un trámite. Los navegadores solo exponen la API Web Crypto, la interfaz que Actual usa para el cifrado de extremo a extremo, dentro de lo que la especificación denomina un contexto seguro. Un contexto seguro es https:// o http://localhost. Cargue la aplicación desde http://203.0.113.10:5006 en un navegador de otra máquina y esas funciones no estarán disponibles, porque el navegador nunca se las proporcionó a la página. Las versiones móviles oficiales también rechazan una URL de servidor http:// sin cifrado.

Por tanto, hay dos configuraciones viables. Coloque un certificado válido para un nombre real delante del contenedor, que es lo que hace esta guía. O proporcione al servidor un certificado autofirmado con ACTUAL_HTTPS_KEY y ACTUAL_HTTPS_CERT, tal como documenta el proyecto, y acepte una advertencia del navegador en cada dispositivo. Un certificado gratuito de Let's Encrypt se obtiene en cinco minutos, así que elija la primera opción.

Instalar Actual Budget con Docker Compose

Instala Docker primero si el servidor es nuevo. Si la sintaxis de los archivos de Compose es nueva para ti, la guía Conceptos básicos de Docker Compose para un VPS explica los campos usados a continuación.

sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/data

Escribe /opt/actual/docker-compose.yml:

services:
  actual:
    image: actualbudget/actual-server:latest
    container_name: actual
    restart: unless-stopped
    ports:
      - '127.0.0.1:5006:5006'
    volumes:
      - ./data:/data

Hay tres detalles importantes en ese archivo.

La imagen es actualbudget/actual-server:latest, publicada por el proyecto en Docker Hub y replicada en ghcr.io/actualbudget/actual. Existe una etiqueta latest-alpine para máquinas de bajo consumo.

El contenedor escribe todo en /data. Dentro de esta ruta encontrarás server-files, que contiene account.sqlite con tus credenciales y tokens de sesión, y user-files, que contiene los archivos del presupuesto. Monta esa ruta o el siguiente docker compose pull eliminará tu presupuesto. ACTUAL_DATA_DIR permite cambiarla, pero el valor predeterminado es correcto.

El puerto se publica únicamente en 127.0.0.1. Un 5006:5006 sin una dirección específica publica el puerto en todas las interfaces, y Docker escribe sus propias reglas antes que ufw. Por tanto, la aplicación quedaría expuesta a Internet incluso con un firewall que deniega todo. Este comportamiento se explica en por qué los puertos publicados por Docker evitan ufw. La vinculación con loopback significa que solo el proxy inverso del mismo servidor puede acceder a ella.

Inícialo:

cd /opt/actual
docker compose up --detach
docker compose logs -f actual

El registro se estabiliza cuando el servidor indica que está escuchando en el puerto 5006. Compruébalo localmente antes de modificar el DNS:

curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/

Un 200 significa que la aplicación está respondiendo. curl: (7) Failed to connect significa que el contenedor no está en ejecución, y docker compose ps mostrará que se detuvo. La causa habitual es un problema de permisos en el volumen montado, visible como una línea EACCES en el registro.

Coloque un certificado y un nombre real delante

Apunte un registro A al VPS, budget.example.com, y espere a que se resuelva. Después instale nginx y emita el certificado. La guía Certbot en Ubuntu 24.04 con nginx explica completamente la emisión y el temporizador de renovación.

El bloque de proxy:

server {
    listen 443 ssl;
    http2 on;
    server_name budget.example.com;

    ssl_certificate     /etc/letsencrypt/live/budget.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/budget.example.com/privkey.pem;

    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:5006;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

client_max_body_size es la línea que se suele olvidar. El archivo de presupuesto se carga completo durante una sincronización completa. Nginx establece de forma predeterminada un cuerpo de solicitud de 1 MB. Cuando el archivo supera ese tamaño, la sincronización falla con 413 Request Entity Too Large en el registro de acceso de nginx, mientras que la aplicación solo muestra un error de sincronización genérico. El servidor tiene sus propios límites independientes: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB tiene un valor predeterminado de 20 y ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB tiene un valor predeterminado de 50. Establezca el límite de nginx por encima del que corresponda en su caso.

Vuelva a cargar la configuración y pruebe:

sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/

Primera ejecución: la contraseña y el primer archivo de presupuesto

Abra https://budget.example.com en un navegador. La primera pantalla le pide establecer una contraseña del servidor. Esa contraseña protege todo el servidor, así que genere una contraseña larga y aleatoria y guárdela en un lugar donde pueda encontrarla de nuevo, como un gestor de contraseñas Vaultwarden autoalojado. No hay cuentas de usuario que crear. El servidor de Actual está diseñado para usar una sola contraseña, por lo que compartir un presupuesto implica compartir esa contraseña.

Después, cree un archivo de presupuesto. Actual le pregunta si desea activar el cifrado de extremo a extremo. Responda que sí; el servidor almacenará solo texto cifrado, que es la opción adecuada para datos financieros en una máquina alquilada. El coste es real: la contraseña de cifrado nunca llega al servidor, por lo que si la pierde, el archivo se pierde y no existe ninguna opción de restablecimiento. Anótela antes de continuar desde esa pantalla.

Establezca los saldos iniciales usando las cifras actuales de su banco en lugar de importar años de historial. El método de presupuestación por sobres parte del dinero que tiene ahora, por lo que no pierde nada al comenzar sin historial.

Importar transacciones

Aquí la honestidad es más importante que el entusiasmo, porque la importación es el principal motivo por el que muchas personas abandonan las aplicaciones de presupuesto autoalojadas.

La introducción manual es la base y siempre funciona. En un método de sobres, posiblemente sea el objetivo, porque escribir una compra hace que le prestes atención.

La importación de archivos gestiona la mayor parte del trabajo. Actual puede leer CSV, QIF, OFX y QFX, y todos los bancos exportan al menos uno de esos formatos. Importa los datos de cada cuenta desde la pantalla de la cuenta, asigna las columnas una vez y Actual recuerda esa configuración para la cuenta.

Existe la sincronización automática con bancos, pero necesita un servicio de terceros porque el servidor no puede comunicarse con los bancos por sí solo. Actual admite SimpleFIN Bridge para bancos de Norteamérica, Enable Banking para Europa, Akahu para Nueva Zelanda y Pluggy.ai para Brasil. GoCardless todavía es compatible, pero ya no acepta cuentas nuevas. Debes registrarte directamente con el proveedor, generar las credenciales y añadirlas al servidor. SimpleFIN Bridge cobra 15 dólares estadounidenses al año por hasta 25 instituciones, según los precios de julio de 2026. Los demás servicios tienen precios diferentes.

Debes aceptar dos limitaciones antes de depender de esta función. Las credenciales de la API se almacenan en el servidor y no están cubiertas por el cifrado de extremo a extremo, porque el servidor debe utilizarlas. Además, Actual no consulta los bancos periódicamente: la sincronización se inicia al pulsar un botón y no mediante una tarea en segundo plano.

Copias de seguridad, porque solo son archivos

Todo lo que le importa está en /opt/actual/data. No hay ningún paso de exportación ni ningún volcado de base de datos que deba automatizar.

El único problema es SQLite. Si copia account.sqlite mientras el servidor escribe en él, puede capturar una transacción incompleta. No lo descubrirá hasta que intente restaurarla. Detenga el contenedor durante los pocos segundos que tarda la copia:

cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose start

Programe esta tarea con el método descrito en copias de seguridad con restic en un VPS. Allí se explican la configuración del repositorio, la retención y la prueba de restauración. Ejecute la prueba de restauración. Una copia de seguridad que nunca se ha restaurado es solo una suposición.

Las copias de seguridad del lado del cliente de Actual son independientes y conviene conocerlas. El navegador conserva copias recientes del archivo de presupuesto, accesibles desde el menú de archivos. Esto permite resolver el caso de «he eliminado una categoría por error» sin tocar el servidor.

Actualización del servidor

cd /opt/actual
docker compose pull
docker compose up --detach

Compose recrea el contenedor a partir de la nueva imagen y vuelve a asociar el mismo volumen, por lo que los datos se conservan. Actualiza también los clientes. Se espera que las versiones del servidor y de la aplicación sean similares. Un cliente mucho más antiguo que el servidor puede negarse a sincronizar y mostrar un mensaje de incompatibilidad de versiones. Haz una copia de seguridad antes de actualizar a una versión principal nueva, porque las migraciones se ejecutan en el primer inicio y no existe una ruta de degradación.

Qué falla y qué verá

La aplicación se carga, pero la sincronización nunca termina. Revise el registro de acceso de nginx para 413. Ese valor de client_max_body_size es demasiado bajo. Un 502 indica que nginx está activo, pero el contenedor no.

Faltan las opciones de cifrado o la aplicación móvil rechaza la URL. La página no está en un contexto seguro. La barra de direcciones mostrará http:// con una dirección IP o un nombre de host que no es localhost. Corrija el certificado en lugar de buscar una solución alternativa.

Aparece un mensaje que indica que el archivo de presupuesto no es compatible con esta versión. Las versiones del cliente y del servidor han dejado de coincidir. Actualice ambos a la misma versión y vuelva a cargar la página.

El contenedor se reinicia en un bucle. Lea docker compose logs actual. Un error de permisos en /data significa que el directorio montado no permite escritura al usuario del contenedor. Un error de dirección en uso significa que otro proceso ya está usando 5006 en loopback.

La primera carga parece lenta. El archivo de presupuesto completo se descarga en el navegador al abrirlo. Primero se realiza una transferencia grande y después se leen los datos localmente. No es un problema de dimensionamiento del servidor y añadir RAM no lo cambiará.

FAQ

¿Actual Budget necesita HTTPS para funcionar?

Sí, en la práctica. El cifrado de extremo a extremo de Actual usa la API Web Crypto del navegador, y los navegadores solo la exponen en un contexto seguro, es decir, https:// o http://localhost. Con HTTP sin cifrar desde otra máquina, esas funciones no están disponibles, y las aplicaciones móviles oficiales rechazan la URL de un servidor HTTP sin cifrar. Use un certificado de Let's Encrypt en un nombre de host real, o un certificado autofirmado con ACTUAL_HTTPS_KEY y ACTUAL_HTTPS_CERT si solo va a usar un navegador de escritorio.

¿Actual puede importar automáticamente las transacciones de mi banco?

Solo mediante un servicio de terceros en el que se registre usted mismo: SimpleFIN Bridge en Norteamérica, Enable Banking en Europa, Akahu en Nueva Zelanda o Pluggy.ai en Brasil. GoCardless es compatible, pero no acepta cuentas nuevas. Esas credenciales de API se almacenan en su servidor y no están cubiertas por el cifrado de extremo a extremo. La sincronización también es manual: debe pulsar un botón y no se consulta nada en segundo plano. La importación de CSV, QIF, OFX y QFX no requiere ningún tercero.

¿Qué tengo que incluir exactamente en la copia de seguridad?

El directorio de datos montado, que es /opt/actual/data en esta guía. Contiene server-files/account.sqlite, con los inicios de sesión y las sesiones, y user-files, con los archivos de presupuesto. Detenga el contenedor antes de copiarlo, porque copiar una base de datos SQLite activa puede capturar una escritura incompleta. Ningún otro elemento del servidor contiene datos de estado.

¿Qué ocurre si pierdo la contraseña de cifrado?

El archivo no se puede recuperar. La contraseña nunca llega al servidor, que es precisamente el objetivo del cifrado de extremo a extremo, por lo que no existe ningún restablecimiento ni procedimiento de asistencia. Guárdela en un gestor de contraseñas en cuanto cree el archivo y conserve una copia en un lugar que no dependa de este mismo servidor.

¿Cuántos recursos del servidor necesita Actual Budget?

Muy pocos. El contenedor sirve archivos estáticos y archivos de datos, y los cálculos del presupuesto se realizan en el navegador. Un vCPU compartido con 1 GB de RAM lo ejecuta sin problemas, y el directorio de datos de un presupuesto doméstico con varios años de historial ocupa unas decenas de megabytes. La falta de espacio en disco se debe a las copias de seguridad y a los demás contenedores, no a Actual.