A background service that automatically runs the bank sync on a scheduled basis on Actual Budget.
- Automatically runs bank sync on all your Actual Budget accounts on a configurable schedule
- Uses the official Actual Budget API for reliable synchronization
- Configurable logging levels for monitoring and debugging
- Runs in a Docker container for easy deployment
The service requires the following environment variables:
ACTUAL_SERVER_URL
: URL of your Actual Budget serverACTUAL_SERVER_PASSWORD
: Password for your Actual Budget serverCRON_SCHEDULE
: Cron expression for scheduling syncs (default:0 1 * * *
- daily at 1am)LOG_LEVEL
: Logging level (default:info
)ACTUAL_BUDGET_SYNC_IDS
: Comma-separated list of budget IDs to sync (e.g. "1cf9fbf9-97b7-4647-8128-8afec1b1fbe2,030d7094-aae8-4d70-aeee-9e29d30d9b88")ENCRYPTION_PASSWORDS
: Comma-separated list of encryption passwords for each account in the ACTUAL_BUDGET_SYNC_IDS list (e.g. "password1,password2") or leave empty if you don't encrypt your data, the position of the password in the list is the position of the account in the ACTUAL_BUDGET_SYNC_IDS list; to skip an account add a comma to the list in that positionTIMEZONE
: Timezone for the cron job (default:Etc/UTC
)RUN_ON_START
: Whether to run the sync on startup (default:false
) - Please note that when setting this totrue
, you may get a notice email from SimpleFin (if you use that service), as they expect only a bank sync once a day.
You can find your budget sync IDs in the Actual Budget app > Selected Budget > Settings > Advanced Settings > Sync ID.
In your Actual Budget Server config, you must be able to log in with a password.
Set the following settings in your Actual Budget Server, then on initial login, you must set a password:
services:
...
actual_budget_server:
image: actualbudget/actual-server:latest
environment: ...
- ACTUAL_OPENID_AUTH_METHOD=openid
- ACTUAL_LOGIN_METHOD=openid
- ACTUAL_ALLOWED_LOGIN_METHODS=openid,password,header
- ACTUAL_OPENID_ENFORCE=false
...
...
docker run -d \
-e ACTUAL_SERVER_URL="your-server-url" \
-e ACTUAL_SERVER_PASSWORD="your-password" \
-e CRON_SCHEDULE="0 1 * * *" \
-e LOG_LEVEL="info" \
-e ACTUAL_BUDGET_SYNC_IDS="1cf9fbf9-97b7-4647-8128-8afec1b1fbe2" \
-e ENCRYPTION_PASSWORDS="password1" \
-e TIMEZONE="Etc/UTC" \
-e RUN_ON_START="false" \
seriouslag/actual-auto-sync:latest
services:
...
actual-auto-sync:
image: seriouslag/actual-auto-sync:latest
environment:
- ACTUAL_SERVER_URL=your-server-url
- ACTUAL_SERVER_PASSWORD=your-password
- CRON_SCHEDULE=0 1 * * *
- LOG_LEVEL=info
- ACTUAL_BUDGET_SYNC_IDS=1cf9fbf9-97b7-4647-8128-8afec1b1fbe2
- ENCRYPTION_PASSWORDS=password1
- TIMEZONE=Etc/UTC
...
- Node.js >= 22
- pnpm >= 10.8.1
-
Install dependencies:
# Clone the repository and `cd` into the folder pnpm install
-
Create a
.env
file with your configuration:ACTUAL_SERVER_URL=your-server-url ACTUAL_SERVER_PASSWORD=your-password CRON_SCHEDULE=0 1 * * * LOG_LEVEL=info ACTUAL_BUDGET_SYNC_IDS=1cf9fbf9-97b7-4647-8128-8afec1b1fbe2 ENCRYPTION_PASSWORDS=your-encryption-password # or leave empty if you don't encrypt your data, the position of the password in the list is the position of the account in the ACTUAL_BUDGET_SYNC_IDS list; to skip an account, add a comma to the list in that position
-
Start the service:
pnpm start
docker build -t actual-auto-sync .
docker run -d \
actual-auto-sync
MIT