Skip to content

feat!: release 2.0, because upgrading from 1.x now needs a step - #652

Merged
GeiserX merged 2 commits into
mainfrom
feat/v2-launch
Nov 7, 2026
Merged

GeiserX merged 2 commits into
mainfrom
feat/v2-launch

Conversation

@GeiserX

@GeiserX GeiserX commented Nov 7, 2026 •

Copy link
Copy Markdown
Owner

Over the last two weeks, releases 1.62 to 1.73 changed what the worker can do on a host, how far an earner can reach into the LAN, and how many IPs one box can earn on. Several of them need a step from the person upgrading: a new compose file, a one-shot volume migration, or a button press to turn on the fence. Nothing in the version number says so. Moving the compose pins from 1.73 to 2.0 makes that explicit, and the docs now explain the whole set in one place.

What this PR does

Desktop needs no follow-up: nothing under services/, the deploy route or the guides changes.

How 2.0 gets cut

release.yml bumps the major version on a type!: subject or a BREAKING CHANGE: footer anywhere in the commits since the last tag. It only runs on pushes that touch app/, services/, Dockerfile*, entrypoint.sh, tunnel/, pyproject.toml or uv.lock, and this PR touches none of those. So merging it alone cuts no release. The next push that touches one of those paths cuts v2.0.0, and then opens the pin PR that moves the compose files to 2.0.

Checks run

  • scripts/generate_readme_tables.py --check: up to date. Positive control: a wrong count in the new page made it fail with "Out of date with the catalog: docs/whats-new-2.0.md".
  • pytest tests/test_app_store_templates.py tests/test_readme_generation.py tests/test_docs_*.py: 312 passed, 8 skipped.
  • python -m zensical build --clean --strict with zensical==0.1.0: no issues. site-check.py site: 87 pages, 0 errors. Negative control: a broken page link and a broken anchor added to the new page made the strict build abort.

Release body for v2.0.0

The release step uses generate_release_notes: true, which only lists PRs. After v2.0.0 is cut, replace its body with this:

CashPilot 2.0 closes the run of releases since 1.62. They changed what the worker can do on your host, how far an earner can reach into your network, and how many IPs one box can earn on. Several need a step from you, so they ship as one major version.

## Why you should upgrade

What an older install leaves open:

- **1.70 and older:** the worker holds the raw Docker socket. Whoever takes over the worker is root on your host.
- **1.72 and older,** with the dashboard and a worker on one host: a compromised worker can read `.fernet_key` and decrypt every provider login you stored.
- **Anything deployed before 1.70:** earners carrying strangers' traffic can reach your LAN, your router and your other machines.

2.0 closes all three. It also carries the fixes since 1.73: the in-app update works behind the socket proxy, confirmed identity backups stay confirmed through the migration, earners from the old pre-worker deploy path stay visible, Podman workers can deploy, and proxy traffic caps recover after a box was offline. Every fix from now on ships in 2.x; the `1.73` tag gets no more patches.

## How to upgrade

The compose files pin a release series, so `docker compose pull` and the in-app Update button stay on 1.x until you do this.

1. **Back up.** The dashboard's `/data` (`cashpilot.db` is your earnings history, `.fernet_key` decrypts every stored login and cannot be recreated). The script is at https://geiserx.github.io/CashPilot/backup-restore/#backup. Then on the Payouts page, press **Download backup** for every box under **Back these up**: a Mysterium keystore or a Storj identity has no other copy.
2. **Take the 2.0 compose file** for each host: `docker-compose.yml`, `docker-compose.fleet.yml`, or `docker-compose.worker.yml` on a worker-only host. Keep your `.env` and your own changes. If your old file already has `cashpilot-socket-proxy` and `cashpilot-migrate`, changing the image tags to `2.0` is enough.
3. **Run** `docker compose up -d --force-recreate` (with `-f` and your file if it is not `docker-compose.yml`), the dashboard host first, then every worker.

**What the one-shot migrator does.** Coming from before 1.73, `cashpilot-migrate` runs once before the proxy starts. Docker cannot add a label to an existing volume, so it copies each earner volume to a `<volume>-pre-isolation` backup, checks it by digest, recreates the volume with the `cashpilot.deployed-by=worker` label, copies the data back, checks again and recreates the earner as it was. A Mysterium identity keeps its address. The worker's own volumes move to `cashpilot_worker_data_owned` and `cashpilot_fleet_owned`. It deletes nothing. It can take a few minutes on a node with a large volume; if it is interrupted, run the same command again and it carries on.

**What you see when it is done.** `docker logs cashpilot-migrate` ends with "Migration complete: everything the worker uses carries cashpilot.deployed-by=worker." The worker's status page says "Docker access: socket proxy". Every earner shows as running, the Fleet page shows 2.0 on each worker, and a Mysterium node keeps its old address. Coming from 1.69 or older, press **Turn on isolation** on each worker's row, then **Check isolation**.

**What works differently.** On the host where the dashboard and a worker run together, the in-app update updates the worker only; update the dashboard with `docker compose pull && docker compose up -d`. Earners you started by hand no longer show in the dashboard; they keep running.

**Rolling back.** 2.0 uses the same database schema as every release since 1.67. To go back to 1.73, set the tags back to `1.73` and run `docker compose up -d`. To go further back, put your old compose file back: the migration kept your old volumes and backups. Run `docker rm -f cashpilot-socket-proxy` if that file predates the proxy, and restore your `/data` backup if you go back past 1.67.

## What's new

### Security
- The worker no longer holds the Docker socket. A socket proxy (sockguard 2.4.6, pinned by digest) holds it, passes only the calls the worker makes, and refuses privileged containers, binds of `/` or of the socket, and unlisted capabilities, devices and runtimes.
- Owner isolation: the worker reaches only containers, volumes and networks labelled `cashpilot.deployed-by=worker`. A compromised worker cannot read the dashboard's data, its encryption key or the keys in its environment. Not yet a full root boundary if you set `CASHPILOT_COMPOSE_DIR` or `CASHPILOT_PROXY_BIND_MOUNTS`.
- New installs fence earners off your LAN, the host, your tailnet and cloud metadata; upgraded installs turn it on with one button. Mysterium, which uses host networking, is not covered, and Podman cannot be fenced yet.
- An optional gVisor runtime for bridge earners, and encrypted backups of node identities from the Payouts page.

### Proxied copies
Run an extra copy of a deployed earner through a SOCKS5, HTTP CONNECT or Tailscale exit-node proxy, so one box earns on several IPs. It fails closed: if the proxy dies, the copy stops instead of leaking out of your own IP. Optional traffic cap per proxy. Services that need host networking, ports, volumes or devices (Mysterium, Bitping, Storj) cannot use one, and UDP goes out only through a Tailscale exit node.

### Also since 1.62
Provider ratings from ten sourced questions, Activity per container (opt-in), custom services by image name, import from money4band, CashFactory and InternetIncome, and CasaOS and Runtipi packages that run the socket proxy.

### Companion apps
- CashPilot Desktop 1.0, the same catalog as an app for macOS, Windows and Linux: https://github.com/GeiserX/CashPilot-Desktop
- CashPilot for Android 1.0, which puts your phone's earning apps on the Fleet page, from GitHub releases and waiting for review on F-Droid: https://github.com/GeiserX/CashPilot-android

What's new, in full: https://geiserx.github.io/CashPilot/whats-new-2.0/
Every upgrade step and leftover: https://github.com/GeiserX/CashPilot/blob/main/UPGRADING.md

Docker Hub

.github/workflows/dockerhub-description.yml already syncs README.md to both drumsergio/cashpilot and drumsergio/cashpilot-worker on every push to main that touches it. This merge triggers that sync, so there is nothing to do by hand. After the merge I check that the run passed and that the Hub page shows the "New in 2.0" block.

BREAKING CHANGE: 2.0 moves the compose pins from 1.73 to 2.0, so docker compose pull and the in-app Update button stay on 1.x until you take the new compose file or change the image tags to 2.0. 2.0 uses the same database as 1.73. Coming from before 1.73, the upgrade runs the one-shot cashpilot-migrate, which copies the worker's volumes onto labelled ones (cashpilot_worker_data_owned, cashpilot_fleet_owned, each earner volume backed up as <volume>-pre-isolation) and deletes nothing. After it, the in-app update no longer updates the dashboard on a host it shares with a worker, and earners started by hand no longer show in the dashboard. Coming from a worker that mounts the Docker socket, the new compose file adds the socket proxy, and the proxy refuses to recreate a CashPilot service with a GPU.

…and proxied copies

Adds the What's new in 2.0 page with an upgrade and rollback section, a 2.0
block in the README and the docs home, a 2.0 entry in UPGRADING.md, and moves
the CasaOS and Runtipi packages to 2.0.0.
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 50 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 45ad696 and d5b2be8.

Files selected for processing: 9

  • README.md
  • UPGRADING.md
  • contrib/app-stores/casaos/CashPilot/docker-compose.yml
  • contrib/app-stores/runtipi/cashpilot/config.json
  • contrib/app-stores/runtipi/cashpilot/docker-compose.yml
  • docs/index.md
  • docs/whats-new-2.0.md
  • scripts/generate_readme_tables.py
  • zensical.toml
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@codecov

codecov Bot commented Nov 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.97%. Comparing base (2d15dae) to head (d5b2be8).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #652   +/-   ##
=======================================
  Coverage   93.96%   93.97%           
=======================================
  Files          74       74           
  Lines       15687    15687           
=======================================
+ Hits        14741    14742    +1     
+ Misses        946      945    -1     

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@GeiserX
GeiserX merged commit 0adeb35 into main Nov 7, 2026
11 checks passed
@GeiserX
GeiserX deleted the feat/v2-launch branch November 7, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant