diff --git a/README.md b/README.md index a8e9ae1..b53fb52 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,18 @@ Local tool that loads bank/card statements (Chase Visa, Ally, CVFCU PDFs; Capital One CSV) into `Bills_Tracker.xlsx` and shows a web dashboard. Everything runs locally; statements and the workbook are **never** committed or baked into the image. -## Run with Docker -```bash -mkdir -p data && cp /path/to/Bills_Tracker.xlsx data/ # statements can be dropped into data/ or uploaded in the page -docker compose up -d # http://127.0.0.1:8765 (loader) /dashboard -``` +## Run on ZimaOS / CasaOS +Add the app: App Store -> Custom Install -> import `compose.yaml` (it follows the ZimaOS `x-casaos` format). +Copy `Bills_Tracker.xlsx` into `/DATA/AppData/money/data/` (the app's data folder), then open the app's Web UI (port 8765). The image is built by Gitea Actions (`.gitea/workflows/build.yml`) and pushed to `git.necloud.us/nate/money`. -Add a repository secret `REGISTRY_TOKEN` (a Gitea access token with `write:package`). +Add a repository secret `REGISTRY_TOKEN` (a Gitea access token with `write:package`), and on the ZimaOS box run +`docker login git.necloud.us` once so it can pull the private image. + +## Run with plain Docker +```bash +mkdir -p data && cp /path/to/Bills_Tracker.xlsx data/ +AppID=money PUID=1000 PGID=1000 TZ=America/New_York docker compose up -d # then edit the bind path in compose.yaml or symlink +``` ## Run without Docker ```bash diff --git a/app.py b/app.py index 7969dab..a3ebce4 100644 --- a/app.py +++ b/app.py @@ -103,6 +103,7 @@ class H(BaseHTTPRequestHandler): self.send_response(code); self.send_header("Content-Type", ctype); self.send_header("Content-Length", str(len(b))) self.send_header("Cache-Control", "no-store"); self.end_headers(); self.wfile.write(b) def _ok_host(self): + if "*" in EXTRA_HOSTS: return True # LAN/NAS use: any hostname or IP (the app has no login, so keep it on a trusted network) h = self.headers.get("Host", ""); return h.rsplit(":", 1)[0] in {"127.0.0.1", "localhost"} | EXTRA_HOSTS or h in EXTRA_HOSTS def do_GET(self): if not self._ok_host(): return self._send(403, {"error": "forbidden"}) diff --git a/compose.yaml b/compose.yaml index 30b38e8..26f313d 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,12 +1,53 @@ +name: money services: money: image: git.necloud.us/nate/money:latest - build: . + container_name: money restart: unless-stopped + user: $PUID:$PGID ports: - - "127.0.0.1:8765:8765" # this app has no login: keep it on localhost (or put it behind your own auth/VPN) + - target: 8765 + published: "8765" + protocol: tcp volumes: - - ./data:/data # put Bills_Tracker.xlsx and your statements here + - type: bind + source: /DATA/AppData/$AppID/data + target: /data environment: - DATA_DIR: /data - # ALLOWED_HOSTS: money.example.lan # hostname only; set if you reach it by another hostname (behind a reverse proxy) + - DATA_DIR=/data + - ALLOWED_HOSTS=* + - TZ=$TZ + x-casaos: + envs: + - container: ALLOWED_HOSTS + description: + en_us: "Hostnames the web page accepts. * = any (the app has no login, so only use it on a trusted network)." + - container: TZ + description: + en_us: Time zone + ports: + - container: "8765" + description: + en_us: Web UI port + volumes: + - container: /data + description: + en_us: "Bills_Tracker.xlsx, your statements (PDF/CSV) and backups. Put Bills_Tracker.xlsx here before first use." +x-casaos: + architectures: + - amd64 + - arm64 + main: money + author: nate + developer: nate + category: Finance + icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/actual-budget.png + tagline: + en_us: Load bank statements into your bills workbook + title: + en_us: Money + description: + en_us: "Drop in Chase, Ally, CVFCU and Capital One statements, see which months are missing, add new transactions to Bills_Tracker.xlsx (with a backup first), and view a bills dashboard. Runs entirely on your server." + port_map: "8765" + index: / + scheme: http