MyMidas/demo/DEPLOY.md
megaproxy 9897d03d91 Add public demo mode with auto-seeding, hourly reset, and Portainer deploy guide
- DEMO_MODE=true env flag: disables password changes and backup endpoints (403),
  exposes GET /demo/status for frontend detection
- Auto-seed on first startup: creates demo user (demo@mymidas.app / demo123)
  with 6 months of transactions, investments, budgets, subscriptions, and tax
  payslips; takes a pg_dump snapshot immediately after for hourly restore
- Hourly reset: resetter Alpine container with cron restores DB from snapshot
  and purges uploaded attachments every hour on the hour
- Frontend: amber demo banner on all pages, login page shows credentials,
  password change disabled with notice, backups section replaced with notice
- demo/ directory: self-contained docker-compose.yml (ports 4001/8091),
  .env.example, reset.sh, and step-by-step Portainer DEPLOY.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 22:08:24 +00:00

4.6 KiB
Raw Blame History

MyMidas Demo — Deployment Guide (Portainer)

This guide deploys the public demo instance on a separate server using Portainer Stacks.

What you get: a fully seeded MyMidas instance at port 4001, with demo data and an hourly auto-reset. No manual steps after initial deploy.


Prerequisites

  • Docker and Portainer installed on the demo server
  • SSH or console access to the demo server (for the initial clone and key generation)
  • Your reverse proxy pointing a public domain at port 4001 on this server

Step 1 — Clone the repo

On the demo server, clone into your preferred location:

git clone https://git.rdx4.com/megaproxy/MyMidas.git
cd MyMidas

Step 2 — Generate JWT keys

The demo shares the secrets/ directory with the main app structure. If you've already generated keys on this server you can skip this.

mkdir -p secrets
openssl genrsa -out secrets/jwt_private.pem 4096
openssl rsa -in secrets/jwt_private.pem -pubout -out secrets/jwt_public.pem

Step 3 — Create the demo .env file

cd demo
cp .env.example .env

Open .env and fill in the three required values:

Variable How to generate
ENCRYPTION_KEY python3 -c "import secrets; print(secrets.token_hex(32))"
DB_PASSWORD Any strong random string
REDIS_PASSWORD Any strong random string

Leave ENVIRONMENT=production.


Step 4 — Deploy the stack in Portainer

  1. Open Portainer → StacksAdd stack
  2. Name it mymidas-demo
  3. Select Repository as the build method
  4. Set the repository URL to your Gitea URL and branch main
  5. Set Compose path to demo/docker-compose.yml
  6. Under Environment variables, add the four variables from your .env:
    • ENCRYPTION_KEY
    • DB_PASSWORD
    • REDIS_PASSWORD
    • ENVIRONMENT = production
  7. Click Deploy the stack

Alternative (upload method): If you prefer to upload the compose file directly, paste the contents of demo/docker-compose.yml into Portainer's web editor and add the environment variables manually.


Step 5 — Wait for first-time seeding

On first startup, the backend will:

  1. Run database migrations
  2. Detect that DEMO_MODE=true and no users exist
  3. Seed the full demo dataset (~180 transactions, investments, budgets, tax data)
  4. Save a compressed snapshot (demo_snapshot.sql.gz) for hourly resets

This takes about 3060 seconds. Watch progress in Portainer → Containersmymidas-demo-backend-1Logs.

You'll see these log lines when ready:

demo_seed_complete
demo_snapshot_created
Uvicorn running on http://0.0.0.0:8000

Step 6 — Configure your reverse proxy

Point your public domain at http://<demo-server-ip>:4001.

The frontend serves the React app and proxies all /api/ calls to the backend internally — so you only need to expose port 4001.

nginx proxy manager example:

  • Scheme: http
  • Forward hostname/IP: <demo-server-ip>
  • Forward port: 4001
  • Enable websockets: off

Step 7 — Verify

Open your domain in a browser. You should see the MyMidas login page with a yellow demo credentials banner:

Email:    demo@mymidas.app
Password: demo123

Log in and confirm the data is populated (accounts, transactions, investments, tax page).


Hourly reset

The resetter container runs a cron job at the top of every hour that:

  1. Restores the database from the snapshot taken on first boot
  2. Deletes any files uploaded by demo users

No action needed — it runs automatically. You can check reset logs in Portainer → Containersmymidas-demo-resetter-1Logs.


Updating the demo

When you push code changes to main:

  1. In Portainer → Stacksmymidas-demoEditorUpdate the stack
  2. This rebuilds the images and restarts all containers
  3. On restart, migrations run automatically; the seed check runs and skips if already seeded (snapshot is preserved on the demo_snapshot volume)

If you want to force a full re-seed (e.g. after adding more demo data): in Portainer, delete the demo_snapshot volume, then redeploy. The backend will re-seed and take a new snapshot on next startup.


Troubleshooting

Symptom Check
Blank page / 502 Backend still starting — wait 60 s and refresh
Login fails Seeding still in progress — check backend logs
Data not resetting Check resetter logs; confirm demo_snapshot volume has the .sql.gz file
"Snapshot not found" in resetter log Backend may not have finished first-time seed — redeploy backend only