Skip to content

Deploying an Actual App

Introduction

Actual is an open-source, privacy-focused personal budgeting application designed to give you complete control over your financial data. It offers envelope-style budgeting, powerful reporting, multi-device sync, and an intuitive web interface—without relying on third-party cloud services.

Deploying Actual on Klutch.sh with a Dockerfile lets you host your own secure budgeting server, keep your data under your control, and make the app available from anywhere. This guide walks through creating a Docker-based Actual deployment, configuring persistent storage, pushing your project to GitHub, and deploying it through the Klutch.sh dashboard at klutch.sh/app.


Prerequisites

Before you start, you’ll need:

  • A Klutch.sh account
  • A GitHub account (GitHub is the only supported git source)
  • Docker installed locally (optional, but recommended for testing your image)
  • Basic familiarity with Docker, environment variables, and self-hosted web apps

Project Setup for Actual

1. Create a Project Directory

Create a new directory to hold your Actual deployment configuration:

Terminal window
mkdir actual-klutch
cd actual-klutch
git init

2. Plan Your Data Directory

Actual stores user data (budgets, accounts, transactions, and sync information) in a data directory inside the container. To ensure that data is not lost when redeploying or restarting the app on Klutch.sh, you’ll mount that directory as a persistent volume.

In this guide, we’ll use /data inside the container as Actual’s data directory. You’ll configure this path as a volume in the Klutch.sh dashboard later.


Creating a Dockerfile for Actual

Klutch.sh automatically detects a Dockerfile in the repository root and uses it for deployments. You don’t select Docker as a dedicated option in the UI, and you do not provide a custom Dockerfile path—the platform discovers and builds from Dockerfile when it’s present.

The example below builds a lightweight Actual server image using the official upstream container as a base.

Create a file named Dockerfile in your project root:

FROM actualbudget/actual-server:latest
# Set where Actual stores its data
ENV ACTUAL_DATA_DIR=/data
WORKDIR /app
# Create the data directory and ensure it exists
RUN mkdir -p /data
# Actual’s web UI and API are served on port 5006 by default
ENV PORT=5006
EXPOSE 5006
# Start the Actual server
CMD ["/bin/sh", "-c", "yarn start"]

Dockerfile Notes

  • This Dockerfile extends the official actualbudget/actual-server image and configures:
    • ACTUAL_DATA_DIR=/data for data storage
    • PORT=5006, which is the port Actual uses for the web UI and API
  • Klutch.sh will route HTTP traffic to your container’s port 5006, which you’ll set as the internal port in the dashboard.
  • You will map /data to a persistent volume on Klutch.sh to preserve budgets and configuration across deployments.

Optional: Local Development with Docker or Docker Compose

You can verify your Actual configuration locally before deploying to Klutch.sh.

Local Docker Run

Terminal window
docker build -t actual-klutch .
docker run -d \
--name actual-test \
-p 5006:5006 \
-v "$(pwd)/actual-data:/data" \
actual-klutch

Then open http://localhost:5006 to access the Actual budgeting app.

Local Docker Compose (Development Only)

For local development only (not for Klutch.sh), you can use Docker Compose:

version: "3.9"
services:
actual:
image: actual-klutch
build: .
ports:
- "5006:5006"
environment:
ACTUAL_DATA_DIR: /data
volumes:
- ./actual-data:/data

Run:

Terminal window
docker compose up --build

Docker Compose is not used by Klutch.sh for deployments; it’s only helpful for local multi-container setups and testing.


Pushing Your Actual Project to GitHub

Once your Dockerfile and any optional configuration files are in place, push the repository to GitHub:

Terminal window
git add .
git commit -m "Initial Actual Docker setup for Klutch.sh"
git branch -M main
git remote add origin https://github.com/your-username/actual-klutch.git
git push -u origin main

Klutch.sh will use this repository as the source for building and running your Actual app.


Creating an Actual App on Klutch.sh

With your GitHub repository ready, you can create and configure the app in the Klutch.sh dashboard.

Connect the Repository

  1. Sign in at klutch.sh/app.
  2. Navigate to Create Project and give your project a descriptive name, such as actual-budget.
  3. Go to Create App and:
    • Select GitHub as the git source.
    • Choose your Actual repository and the branch you wish to deploy (for example, main).

Klutch.sh will automatically detect the Dockerfile in the repository root and use it to build your image.

Traffic Type and Internal Port

  • Traffic Type: Select HTTP (Actual exposes a web UI and HTTP API).
  • Internal Port: Set to 5006 to match the EXPOSE 5006 and PORT=5006 configuration in your Dockerfile.

This ensures incoming HTTP requests are correctly routed to the Actual app inside the container.

Environment Variables on Klutch.sh

At a minimum, you may want to configure:

  • ACTUAL_DATA_DIR – set to /data (default in the Dockerfile), so Actual stores all user data in the path you’ll mount as a persistent volume.
  • TZ – your timezone (for example, UTC or America/New_York) for more accurate timestamp handling.

If you choose to deploy Actual without a Dockerfile and rely on Nixpacks for automatic builds, you can customize build and start commands via environment variables:

  • BUILD_COMMAND – override the default build command Nixpacks uses.
  • START_COMMAND – override the default start command Nixpacks runs.

Set these environment variables in the Klutch.sh dashboard when configuring a Nixpacks-based deployment.


Attaching Persistent Volumes

Persistent storage is critical for Actual, since your budgets, accounts, and transaction history must survive restarts and redeploys.

In the app’s Storage/Volumes section:

  • Actual Data Volume
    • Mount path: /data
    • Size: Choose a size based on your retention goals and expected number of users (for example, 5 GiB to start, with room to grow as needed).

By mounting /data as a persistent volume, Actual’s data directory will be preserved across container updates and redeploys.


Sample Usage: Connecting to Actual from a Browser

Actual is primarily accessed via its web interface, but you may also want to integrate it with browser extensions or external clients that talk to the server.

Assuming your Actual app is deployed at:

https://example-app.klutch.sh

You can access the budgeting UI directly in the browser by visiting that URL. For simple programmatic health checks from JavaScript, you might do:

async function checkActualServerHealth() {
try {
const response = await fetch('https://example-app.klutch.sh/', {
method: 'GET',
});
if (!response.ok) {
throw new Error(`Actual server returned status ${response.status}`);
}
console.log('Actual server is reachable.');
} catch (error) {
console.error('Error reaching Actual server:', error);
}
}
checkActualServerHealth();

This pattern can be extended to integrate Actual with other tooling or dashboards that simply need to confirm that the budgeting app is online and reachable.


Verifying Your Deployment

After deployment finishes successfully in the Klutch.sh dashboard:

  1. Visit your app URL, for example:

    https://example-app.klutch.sh
  2. Confirm that:

    • The Actual login/setup page loads correctly.
    • You can create or restore a budget.
    • Budgets and transactions remain available after restarting the app, confirming that the /data persistent volume is configured correctly.

If anything fails, double-check your internal port setting (5006), traffic type (HTTP), and persistent volume mount path.


Troubleshooting

Actual UI Not Loading

  • Ensure that the app’s traffic type is HTTP, not TCP.
  • Verify the internal port is set to 5006 and matches the EXPOSE 5006 configuration in your Dockerfile.
  • Check deployment logs in the Klutch.sh dashboard for errors from the Actual server or Node.js runtime.

Data Not Persisting Across Deployments

  • Confirm that a persistent volume is attached with mount path /data.
  • Make sure ACTUAL_DATA_DIR is set to /data in your environment variables or Dockerfile.
  • Verify that the volume has sufficient space and that the container can write to the directory.

Build or Image Issues

  • Ensure that the actualbudget/actual-server:latest image is accessible from your environment when building the Dockerfile.
  • If you fork or build Actual from source instead, adapt the Dockerfile accordingly (install dependencies, build the app, and expose port 5006).
  • Check the Klutch.sh build logs for specific error messages.


Deploying an Actual app on Klutch.sh with a Dockerfile gives you a secure, self-hosted budgeting solution that keeps your financial data under your control. With a simple Dockerfile, correctly configured internal port, and a persistent volume for /data, you can run a reliable Actual instance on Klutch.sh and access your budgets from anywhere with confidence.