FAQ & troubleshooting
Answers to the questions new self-hosters actually hit — login, CORS, ports, uploads, data.
Setup & login
The login screen says "Could not reach API — check Server URL"
The SPA can't reach the API. Docker all-in-one: leave the Server field blank (the UI
uses same-origin /api/v1). Split CDN + API: set Server to your API origin, e.g.
https://api.example.com — /api/v1 is appended automatically.
I never saw the setup wizard / it says "setup already complete"
The wizard only appears while the database has zero users. If a user exists, sign in
normally. Starting truly fresh means wiping the data volume
(docker compose down -v — this deletes your journal).
Why can't anyone register?
By design. After the owner is created, POST /auth/register returns 403 unless you set
TM_ALLOW_REGISTRATION=true. Admins can also add users from the CLI:
docker compose exec api /tradermemos create-user --email … --password …
My password is rejected
Passwords must be at least 10 characters.
I forgot my password
There's no self-service reset (your server has no mail service to send one). The admin CLI inside the API container resets it:
docker compose exec api /tradermemos reset-password --email you@example.com --password '…'Server & deployment
The API refuses to start: "insecure JWT secret"
Intentional. Set a real secret — TM_JWT_SECRET=$(openssl rand -hex 32) — or, for throwaway
local runs only, TM_ALLOW_INSECURE_JWT=true (the bundled Compose does this for first-run
convenience; unset it in production).
Port 3000 (or 8080) is already in use
Change the host-side port mapping in docker-compose.yml (e.g. "3001:80" on web). The
API's own port is TM_HTTP_PORT.
Browser console shows CORS errors
Only split deployments (UI and API on different origins) need CORS. Set TM_CORS_ORIGINS on
the API to your exact SPA origin(s) — wildcards like https://*.vercel.app work. Same-origin
setups (Docker all-in-one, edge rewrites) should leave it empty.
Can I run the API on Vercel or Cloudflare Workers?
No — it's Go + SQLite + file uploads and needs a real disk. Host the API on Docker, a VPS, NAS, or Railway (with a volume); the one-click buttons deploy the web UI only. See Fork & deploy.
Where exactly is my data?
Docker: the tm_data volume — /data/tradermemos.db plus /data/attachments. That volume
is your journal; see Backup & restore.
SQLite or Postgres?
SQLite (default) is right for a personal instance — zero extra moving parts, one file to back
up. Postgres (make up-postgres) suits multi-user or existing-infra setups. Moving between
them: export ZIP, re-import.
Features
Uploads fail with 413
The file exceeds a cap. API caps default to 10 MiB each (TM_ATTACH_MAX_BYTES,
TM_IMPORT_MAX_BYTES, TM_OCR_MAX_BYTES); the bundled nginx allows 20 MB. Raise the
relevant cap — and your reverse proxy's client_max_body_size —
see Configuration.
I imported the same file twice — do I have duplicates?
No. Fills are deduplicated by symbol + side + quantity + price + timestamp; repeats count as Skipped. A bad import can also be reversed as a batch from the Import page.
My broker isn't listed as supported
Check Supported brokers first — presets cover the common platforms, and MT4/MT5 statements import as-is. For anything else, any CSV with symbol / side / quantity / price / date columns imports via column mapping; auto-detection recognizes most common header names.
Screenshot scan times out or errors
Check Settings → AI → Test, confirm the model supports vision, and for slow/local models
raise TM_OCR_VISION_TIMEOUT_SEC plus your proxy's read timeout
(see Reverse proxy). "503 not configured" means
enable + base URL + key haven't all been saved.
Is my trading data sent anywhere?
No. Everything stays on your server. The exceptions, all under your control: AI features call
the endpoint you configure; market data (on by default, TM_MARKET_DATA_ENABLED) and the
economic calendar (on by default, TM_ECON_CALENDAR_ENABLED) fetch public data from their
providers; alert channels you create deliver to your webhook URLs or Expo push; and a share
link you create makes that stats page public until you revoke it (TM_SHARE_LINKS_ENABLED,
off by default).
Still stuck?
- Check the API logs:
make logs(ordocker compose logs -f api) curl http://localhost:3000/healthz— confirms the API is up and shows the version- Open an issue with the log output