Skip to content

Repository files navigation

Spendable

Privacy focused budgeting.

Development

Postgres runs in docker compose; everything else runs on the host.

docker compose up -d db
mix setup
mix phx.server

Then visit localhost:4000. Sign-in is Google OAuth, so .env needs GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, PLAID_CLIENT_ID and PLAID_SECRET_KEY.

Worktrees

In a git worktree, run this first:

scripts/setup-worktree.sh

It gives the worktree its own database (spendable_dev_wt1) and port (4100, 4200, ...) on the one shared postgres, writes them to a gitignored .env.worktree that mise and docker compose both read, and copies .env over from the main checkout. Then mix setup and mix phx.server as usual.

Gates before anything is done:

mix format && mix compile --warnings-as-errors && mix credo && mix coveralls

Production

One script installs the whole stack — it prompts for each credential, writes them where the release expects them, and builds and starts everything.

scripts/install.sh

It brings up postgres, creates and migrates the spendable database, and runs the release built from the Dockerfile. Answering yes to the Cloudflare tunnel prompt also runs cloudflared, so the app is published on your hostname without opening a port on the machine — create the tunnel first at one.dash.cloudflare.com → Networks → Tunnels, point its public hostname at http://app:4000, and paste the connector token when asked.

Credentials go to .secrets/ as one 0600 file per value, because the release reads them as files from /etc/secrets rather than from its environment. .env.prod (also 0600) holds the three values docker compose itself needs. Both are gitignored, and nothing is echoed back or left in shell history.

Re-run the script any time to change a credential; every prompt offers to keep what is already there.

To deploy a new version, pull and rebuild in one step:

scripts/update.sh

It pulls (unless the working tree is dirty), rebuilds the image, runs migrations, and recreates whatever the compose file changed — including removing services it no longer defines.

Either script can be replaced with the compose command it runs:

docker compose --env-file .env.prod --profile prod --profile tunnel up -d --build

Drop --profile tunnel if you are not tunnelling. PROD_PORT in .env.prod sets the published port, so a local run can sit alongside a mix phx.server already holding 4000.

Architecture

About

Privacy focused budgeting

Resources

Stars

17 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages