Actual, a local-first personal finance tool

Overview

This is the main project to run Actual, a local-first personal finance tool. It comes with the latest version of Actual, and a server to persist changes and make data available across all devices.

Join the discord!

Non-technical users

We are working on simpler one-button click deployments of Actual. This will reduce the friction for people not as comfortable with the command line. Some non-official options are listed at the bottom.

Running

It's very easy to get started. Clone this repo, install deps, and start it:

git clone https://github.com/actualbudget/actual-server.git
cd actual-server
yarn install
yarn start

Go to https://localhost:5006 in your browser and you'll see Actual.

Running via Docker

To run using a Docker container you can use following commands;

git clone https://github.com/actualbudget/actual-server.git
cd actual-server
docker build -t actual-server .
docker run -p 5006:5006 actual-server

Deploying

You should deploy your server so it's always running. We recommend fly.io which makes it incredibly easy and provides a free plan.

fly.io allows running the application directly and provides a free tier. You should be comfortable with using the command line to set it up though.

Create an account. Although you are required to enter payment details, everything we do here will work on the free tier and you won't be charged.

Next, install the flyctl utility. Run flyctl auth login to sign into your account.

Copy fly.template.toml to fly.toml. Open fly.toml and customize the app name on the first line of the file.

Now, run flyctl launch from actual-server. You should have a running app now!

Whenever you want to update Actual, update the versions of @actual-app/api and @actual-app/web in package.json and run flyctl deploy.

Using a custom Docker setup

Actual is also available as a Docker image ready to be run in your own custom environment.

  • Docker Hub: jlongster/actual-server
  • Github Registry: ghcr.io/actualbudget/actual-server

Persisting server data

One problem with the above setup is every time you deploy, it will wipe away all the data on the server. You'll need to bootstrap the instance again and upload your files.

Let's move the data somewhere that persists. With fly.io we can create a volume. Run this command:

flyctl volumes create actual_data

Now we need to tell Actual to use this volume. Add this in fly.toml:

[mounts]
  source="actual_data"
  destination="/data"

That's it! Actual will automatically check if the /data directory exists and use it automatically.

You can also configure the data dir with the ACTUAL_USER_FILES environment variable.

One-click hosting solutions

These are non-official methods of one-click solutions for running Actual. If you provide a service like this, feel free to open a PR and add it to this list. These run Actual via a Docker image.

Configuring the server URL

The Actual app is totally separate from the server. In this project, they happen to both be served by the same server, but the app doesn't know where the server lives.

The server could live on a completely different domain. You might setup Actual so that the app and server are running in completely separate places.

Since Actual doesn't know what server to use, the first thing it does is asks you for the server URL. If you are running this project, simply click "Use this domain" and it will automatically fill it in with the current domain. This works because we are serving the app and server in the same place.

Comments
  • Add Github Actions workflow to automatically build a Docker image

    Add Github Actions workflow to automatically build a Docker image

    Add Github Actions workflow to automatically build a Docker image on the creation of tags to version the changes of the Actual server. The Docker image is pushed to both the Docker Hub and the Github Container Registry.

    Caution: the following variables/secrets must be configured by the maintainer in the project settings:

    • DOCKERHUB_USERNAME - User name on the Docker Hub
    • DOCKERHUB_TOKEN - Token instead of a password, can be created in the Docker Hub account settings
    opened by Kovah 33
  • Use Alpine Linux as base image for docker container

    Use Alpine Linux as base image for docker container

    This change reduces image size by 80%

    actual-alpine   latest            61b69b88643e   12 minutes ago   192MB
    actual-debian   latest            43fa732027dc   17 minutes ago   1.09GB
    

    Also use tini as "container init" allowing a gracefully shutdown of container

    opened by ldotlopez 28
  • Fix 'Out of sync' error

    Fix 'Out of sync' error

    When I've tried to modify some account (add a transaction) on second computer, I've got "Your data is out of sync" error on first.

    image

    This PR should fix sync error message.

    NOT Done:

    • handle the encryptKeyId for encrypted messages;
    opened by 7brend7 23
  • Transition to typescript

    Transition to typescript

    • adds basic typescript support. scripts for typechecking and compilation
    • updated dockerfiles
      • include a build step
      • best practices (with references in the commits).
      • The RUN consolidation might need discussion, as it could have an effect on caching that you find undesirable
    • app-plaid.js seems to be unused. there's no plaid dependency in the the package, and I didnt spot any references to app-plaid. I haven't removed it, but it seems like a candidate for removal
      • util/handle-error also unused
      • sync-simple also unused
    • No files have been rewritten to add typings or other TS specific changes in this PR. One fix was made as a result of running the typechecker.
      • initial file conversion and very rough typings (ie there are still anys, which is unpleasant) in a separate branch. At least one typing looks like it should be defined/is dependent on @actual-app/api
    • clean script for build artifacts currently uses rm -rf, which isn't portable as far as i know. rimraf and other solutions may be portable, but I didnt want to add those without discussion

    I'm assuming this is still part of the plan based on this. Both docker builds have been updated and seem to be working in my limited testing.

    Running locally without docker feels a little convoluted as I currently have it set up. There's only one extra command, but atm I'm copying node_modules and that feels...odd. Including something like ts-node would let us JIT compile any typescript and avoid the current inconvenience, but I didn't want to introduce that dependency (even if it's only for local runs) without some sort of consensus.

    Adding typescript-eslint would also make sense, though I have no idea what specific rules you'd like to enforce. I can set it up with the defaults as a starting point, if desired (done in this branch).

    opened by PartyLich 16
  • Add one-click hosting option

    Add one-click hosting option

    This adds the one-click hosting option mentioned in the README. Will use the official Docker image, once it's available.

    About PikaPods: We just finished our beta program and focus on making privacy-conscious open source apps more accessible. Currently our app store offers around 50 apps and we run around 1500 pods. Currently there are 2 different regions, US and EU, with a third in Hong Kong joining soon. Users always have full access to their data over SFTP. We only sell hosting, so there are no ads, trackers or other limitations.

    Button preview

    opened by m3nu 15
  • Accounts get mixed up when syncing multiple files

    Accounts get mixed up when syncing multiple files

    Steps to reproduce:

    1. create file 1, add some accounts, close file 1

    2. create file 2, add some accounts, close file 2

    3. open file 1: file 1 now only shows the accounts that are defined in file 2

    4. close file 1, open file 2: file 2 still shows the accounts defined in file 2, but shows the name of file 1 in the upper left corner

    5. close file 2, "delete file 2 locally", "delete file 2 from all devices", "clear site data" in Chrome dev tools

    6. login to actual again

    7. open file 1: file 1 now shows ALL accounts from file 1 and the deleted file 2, upper left corner still shows the name of deleted file 2

    OS: macOS 12.3.1 on arm64 Browser: Google Chrome v100.0.4896.127 and v101.0.4951.41

    opened by juriroemer 11
  • Add Dockerfile.alpine for alpine buil; add tini to debian image

    Add Dockerfile.alpine for alpine buil; add tini to debian image

    This PR adds a separate Dockerfile.alpine to build an image based on Alpine Linux. The resulting image will be just over 100M in size. The build and resulting image works on AMD64 (Tested on Ubuntu 20.04) and ARM64 (Tested on a RPI3 with Ubuntu 22.04)

    During testing i switched between the yarn start and node app.js start commands and when using the latter, the container will exit with code 143 (which i think is the correct code) as opposed to exit code 1 when using yarn start. So i included the node app.js command for now.

    opened by brtwrst 10
  • Irreparable

    Irreparable "Your data is out of sync" when using account on multiple devices.

    👋 Not sure if this is a dupe of https://github.com/actualbudget/actual-server/issues/23, so filing separately just in case.

    Setup

    I'm currently running Actual on a GCP instance, using this Dockerfile as part of a larger docker-compose, at this hash: 44d045f546ceb2440f2a681bc5821bbb8eefb80f. Nothing seems to have been merged into master since then that would impact this.

    Steps to reproduce

    1. Open web UI on two distinct devices, downloading the same account.
    2. On device A, add a new transaction.

    Problematic behavior

    On device B, you'll get this error on next sync (or load) even. Note that you don't need to add or change anything on B.

    a

    If you press repair:

    b

    Expected behavior

    I expected to be able to sync and work on an account across multiple devices, given the CRDT logic.

    opened by jokeofweek 9
  • landed in an un-syncable state

    landed in an un-syncable state

    Was trying out this app for the first time, made like a test thingy in my local machine. Took the docker-compose file from #7 and it worked well for a while. The locally kept files synced with the docker ones, persisted between restarts as well. But after a few changes, seems like I landed in this un-syncable state where I've lost a few set of rows & this doesn't sync anymore.

    Exporting and importing doesn't work as well. Any suggestions?

    https://user-images.githubusercontent.com/8632659/166166160-ae0c02f0-78b2-4d65-9007-955d4082f063.mov

    Note: This has nothing to do w/ the PR - I just wanted to clarify I used it NOT from master.

    opened by dixitk13 8
  • Forgot Password

    Forgot Password

    I forgot my password, I logged into the server using docker exec -ti actual-server sh, but I can't seem to find the location where the password is stored. Can anyone advice? Thanks!

    opened by notflip 7
  • Build docker image on push to master or tag

    Build docker image on push to master or tag

    ~~Facilitates folks trying out any new merged changes, not just ones the project considers "ready for release." Didn't include here, but we might also consider building on every git tag, since those are rare.~~

    PR has changed a lot based on feedback. See below for details.

    Summary

    Merging this change will result in Docker images with the following tags being built on every push to master: edge sha-<commit_sha> (as well as the same tags suffixed with -alpine)

    When a git tag containing v*.*.* is pushed to the repo, e.g. v3.1.4 (or even v1.2.3-long-description, see Usage below), the following tagged Docker images will be built: latest 3.1 3.1.4 sha-<commit_sha> (as well as the same tags suffixed with -alpine)

    Usage

    • Folks who want bleeding edge code can always use actual-server:edge
    • Folks who want a stable Actual can rely on actual-server:latest
    • Anyone can lock to a specific commit at actual-server:sha-<commit_sha>
    • Maintainers can push other tags, e.g. v1.5.6-beta, v2.3.0-responsive-preview as needed and images will be made available for testers
    opened by trevdor 6
  • Support for accounts with more than 100 millions

    Support for accounts with more than 100 millions

    Context: Im from Colombia, a dollar is equivalent to 5000 colombian pesos. I have a mortgage of 200M pesos.

    Problem, when I create a mortgage with value 214'390720 I'm receiving this error

    "[Exception] Error: Can't convert to integer: 21439072000"

    Note the additional two 0s at the end

    opened by crorodriguezro 3
  • armv7 support

    armv7 support

    It seems that what's available on Docker Hub are amd64 and arm64 images, but sadly no armv7 image. I'd love to be able to run actual-server on some older armv7 boards I have, and was wondering if support could be added.

    opened by kn100 1
  • Bug: able to create Schedule that you cannot view linked transactions for

    Bug: able to create Schedule that you cannot view linked transactions for

    Steps to replicate:

    1. Create a new schedule
    2. Edit the schedule as a rule
    3. Remove the amount and/or date constraints from the rule
    4. Save the rule/schedule
    5. Reopen the schedule
    6. Click "Find Matching Transactions"

    You'll get an error like the following:

    react-dom.production.min.js:4928 TypeError: Cannot read properties of undefined (reading 'map')
        at EditSchedule.js:310:31
        at uu (react-dom.production.min.js:5012:1)
        at El (react-dom.production.min.js:6336:1)
        at t.unstable_runWithPriority (scheduler.production.min.js:309:1)
        at Hi (react-dom.production.min.js:2742:1)
        at kl (react-dom.production.min.js:6316:1)
        at react-dom.production.min.js:6305:1
        at U (scheduler.production.min.js:203:1)
        at O.port1.onmessage (scheduler.production.min.js:94:1)
    ru @ react-dom.production.min.js:4928
    o.componentDidCatch.n.callback @ react-dom.production.min.js:5454
    ho @ react-dom.production.min.js:3030
    lu @ react-dom.production.min.js:5036
    (anonymous) @ react-dom.production.min.js:6253
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    _l @ react-dom.production.min.js:6060
    sl @ react-dom.production.min.js:5755
    (anonymous) @ react-dom.production.min.js:2776
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    $i @ react-dom.production.min.js:2772
    Yi @ react-dom.production.min.js:2762
    El @ react-dom.production.min.js:6349
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    kl @ react-dom.production.min.js:6316
    (anonymous) @ react-dom.production.min.js:6305
    U @ scheduler.production.min.js:203
    O.port1.onmessage @ scheduler.production.min.js:94
    react-dom.production.min.js:4928 TypeError: Cannot read properties of undefined (reading 'captureException')
        at w.componentDidCatch (App.js:79:27)
        at o.componentDidCatch.n.callback (react-dom.production.min.js:5456:1)
        at ho (react-dom.production.min.js:3030:1)
        at lu (react-dom.production.min.js:5036:1)
        at react-dom.production.min.js:6253:1
        at t.unstable_runWithPriority (scheduler.production.min.js:309:1)
        at Hi (react-dom.production.min.js:2742:1)
        at _l (react-dom.production.min.js:6060:1)
        at sl (react-dom.production.min.js:5755:1)
        at react-dom.production.min.js:2776:1
    ru @ react-dom.production.min.js:4928
    n.callback @ react-dom.production.min.js:5432
    ho @ react-dom.production.min.js:3030
    lu @ react-dom.production.min.js:5052
    (anonymous) @ react-dom.production.min.js:6253
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    _l @ react-dom.production.min.js:6060
    sl @ react-dom.production.min.js:5755
    (anonymous) @ react-dom.production.min.js:2776
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    $i @ react-dom.production.min.js:2772
    Yi @ react-dom.production.min.js:2762
    El @ react-dom.production.min.js:6349
    t.unstable_runWithPriority @ scheduler.production.min.js:309
    Hi @ react-dom.production.min.js:2742
    kl @ react-dom.production.min.js:6316
    (anonymous) @ react-dom.production.min.js:6305
    U @ scheduler.production.min.js:203
    O.port1.onmessage @ scheduler.production.min.js:94
    scheduler.production.min.js:96 Uncaught TypeError: Cannot read properties of undefined (reading 'captureException')
        at w.componentDidCatch (App.js:79:27)
        at o.componentDidCatch.n.callback (react-dom.production.min.js:5456:1)
        at ho (react-dom.production.min.js:3030:1)
        at lu (react-dom.production.min.js:5036:1)
        at react-dom.production.min.js:6253:1
        at t.unstable_runWithPriority (scheduler.production.min.js:309:1)
        at Hi (react-dom.production.min.js:2742:1)
        at _l (react-dom.production.min.js:6060:1)
        at sl (react-dom.production.min.js:5755:1)
        at react-dom.production.min.js:2776:1
        
    

    I came across this because I was trying to set up a schedule for a rent payment I receive from a roommate which can vary in date/amount depending on the month. Not sure whether I'm "holding it wrong" or not by trying to do that, but the bug is unexpected.

    opened by zbuc 0
  • :white_check_mark: (adding jest for unit/integration tests)

    :white_check_mark: (adding jest for unit/integration tests)

    Adding jest for unit/integration test support.

    This is the first step in order to make the API more stable and reliable before starting to add new functionality (https://github.com/actualbudget/actual/discussions/388).

    LMK if you want me to change some things around.

    opened by MatissJanis 1
  • Allow config.json to contain a partial config

    Allow config.json to contain a partial config

    This is a small PR that changes how load-config.js loads a config from config.json. This would allow for config.json to contain "partial" configs.

    Example config.json

    {
        "port": 5007,
        "hostname": "127.0.0.1"
    }
    

    This would override the config.port and config.hostname but config.userFiles and config.serverFiles would be defaulted.

    needs-testing waiting-review 
    opened by nfaucher8 0
  • Upgrading to version 22.10.25 not working in Docker

    Upgrading to version 22.10.25 not working in Docker

    Hey there,

    I just tried to update to the latest version 22.10.25 of actual budget using docker Portainer. Download works fine, but after that the container stays in the state created. When trying to start the service manually I got an HTTP error 400.

    Are there any breaking changes that would cause such a behavior?

    I use the following docker compose

    version: "3"
    services:
      actual_server:
        image: jlongster/actual-server:latest
        container_name: actual_server
        ports:
          - "5006:5006"
        volumes:
          - /local_data:/data/
        restart: unless-stopped
    
    opened by Marcus-Schubert 4
Owner
null
Finance-Tracker - A basic finance-tracker application built using Next.js, React Hooks and Context API

Next.js + Tailwind CSS Example This example shows how to use Tailwind CSS (v3.0) with Next.js. It follows the steps outlined in the official Tailwind

Osemwengie Benjamin 1 Jan 2, 2022
Macarena finance is a simple UI for Yearn Finance, made to be forked!

Macarena Finance Macarena finance is a simple UI for Yearn Finance, made to be forked! Running your own instance of Yearn makes you eligible to earn f

yearn 17 Oct 1, 2022
Displaying actual age in percentage with 9 signs after dot (floating number)

Actual Age Chrome Extension Displaying actual age in percentage with 9 signs after dot (floating number) Features Popup You can select your Birth date

Igor Makeenko 22 Nov 2, 2022
Transform URLs in strings to actual links.

Transform URLs in strings to actual links. It will find valid links in the given string and create <a> tags for it. Internally, it uses this Regex to

Prince Neil Cedrick Castro 7 Nov 4, 2022
A lightweight (the actual ship is heavy though), performat & powerful sharder for Discord.JS. Indomitable uses cluster module to evenly spread her weight (load) across your cores

Indomitable A lightweight (the actual ship is heavy though), performat & powerful sharder for Discord.JS. Indomitable uses cluster module to evenly sp

Saya 17 Nov 29, 2022
A lightweight JavaScript library that renders text in a brilliant style by displaying strings of random characters before the actual text.

cryptoWriter.js A lightweight javascript library which creates brilliant text animation by rendering strings of random characters before the actual te

Keshav Bajaj 2 Sep 13, 2022
Powercord plugin to make "divider" roles into actual dividers

Powecord Role Dividers Install in Replugged Turns "divider" roles into actual dividers. Before: After: A divider role I have is not being shown as a d

Albert Portnoy 7 Dec 28, 2022
A personal semantic search engine capable of surfacing relevant bookmarks, journal entries, notes, blogs, contacts, and more, built on an efficient document embedding algorithm and Monocle's personal search index.

Revery ?? Revery is a semantic search engine that operates on my Monocle search index. While Revery lets me search through the same database of tens o

Linus Lee 215 Dec 30, 2022
Landing Page for Villagers.finance Play To Earn WEB3 Game, NFT Based.

create-svelte Everything you need to build a Svelte project, powered by create-svelte. Creating a project If you're seeing this, you've probably alrea

Ahmed DEMIAI 9 Sep 15, 2022
🍯 An open source interface for the Honey Finance protocol

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Honey Labs 33 Dec 17, 2022
Decentralized Finance platform (frontend)

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: ya

DJS Tech Group-Dev 2 Mar 28, 2022
A high-resolution local database that uses precise algorithms to easily record data in local files within a project with persistent JSON and YAML support designed to be easy to set up and use

About A high-resolution local database that uses precise algorithms to easily record data in local files within a project with persistent JSON and YML

Shuruhatik 5 Dec 28, 2022
Use Matrix as a backend for local-first applications with the Matrix-CRDT Yjs provider.

Matrix CRDT Matrix-CRDT enables you to use Matrix as a backend for distributed, real-time collaborative web applications that sync automatically. The

Yousef 604 Jan 7, 2023
⚡ the first open-source redis client made with care and acessibility-first 🚀

⚡ Redis UI The first open-source project to create an awesome and accessible UI for Redis as a native desktop application. ✨ ?? ?? How to develop loca

Nicolas Lopes Aquino 14 Dec 5, 2022
The LMS (Life Management System) is a free tool for personal knowledge management and goal management based on Obsidian.md.

README Documentation | 中文帮助 The LMS (Life Management System) is a tool for personal knowledge management and goal management based on Obsidian.md. It

null 27 Dec 21, 2022
📸 A command-line tool to generate code images of your local code right away from the terminal

?? rayli ?? A command-line tool to generate code images of your local code right away from the terminal Usage Commands Usage $ npm install -g rayli $

buidler's hub 45 Nov 4, 2022
MerLoc is a live AWS Lambda function development and debugging tool. MerLoc allows you to run AWS Lambda functions on your local while they are still part of a flow in the AWS cloud remote.

MerLoc MerLoc is a live AWS Lambda function development and debugging tool. MerLoc allows you to run AWS Lambda functions on your local while they are

Thundra 165 Dec 21, 2022
A refined tool for exploring open-source projects on GitHub with a file tree, rich Markdown and image previews, multi-pane multi-tab layouts and first-class support for Ink syntax highlighting.

Ink codebase browser, "Kin" ?? The Ink codebase browser is a tool to explore open-source code on GitHub, especially my side projects written in the In

Linus Lee 20 Oct 30, 2022
Grassp is the first ever CLI based Micro Learning Tool!

grassp-cli Grassp is the first ever CLI based Micro Learning Tool! grassp-cli Usage Commands Usage $ npm install -g grassp $ grassp COMMAND running co

Sahil Pabale 9 Aug 9, 2022