Document verified Dokku deployment and live sync results

This commit is contained in:
Peter Stockings
2026-10-01 20:47:58 +10:00
parent 8555695c5e
commit fe9888092c
2 changed files with 30 additions and 11 deletions
+10 -9
View File
@@ -26,8 +26,8 @@ account exists. Subsequent accounts start empty.
The local app uses SQLite in `instance/dashboard.db`. Set `DATABASE_URL` to a The local app uses SQLite in `instance/dashboard.db`. Set `DATABASE_URL` to a
PostgreSQL connection string to use PostgreSQL. Database changes use Alembic PostgreSQL connection string to use PostgreSQL. Database changes use Alembic
migrations. Local schema creation/upgrade has been verified on SQLite; PostgreSQL migrations. SQLite and deployed PostgreSQL migrations have been verified; see
runtime validation is recorded in docs/DEPLOYMENT.md. [deployment validation](docs/DEPLOYMENT.md).
### Accounts and sharing ### Accounts and sharing
@@ -49,9 +49,10 @@ runtime validation is recorded in docs/DEPLOYMENT.md.
### Bringing in more activities ### Bringing in more activities
Run the local sync below, then choose **Settings & imports -> Load new downloads**. Use **Settings & imports -> Connect Garmin** to upload an exported session, then
This button imports the cache assigned to your account, without contacting Garmin. choose **Sync now** or leave hourly sync enabled. Any account can also upload an
Any account can also upload an original FIT file through Settings & imports. original FIT file through Settings & imports. Operators can import local caches
with the command below.
Original files remain private and are not exposed by web download routes. Original files remain private and are not exposed by web download routes.
If multiple Garmin caches existed at setup, an operator can explicitly assign one: If multiple Garmin caches existed at setup, an operator can explicitly assign one:
@@ -61,10 +62,10 @@ uv run --locked flask --app app import-local --email owner@example.com --account
``` ```
The application uses CSRF protection, hashed passwords, login throttling, and The application uses CSRF protection, hashed passwords, login throttling, and
server-side authorization on every activity page and data endpoint. Before public server-side authorization on every activity page and data endpoint. Email
deployment, finish email verification/recovery, shared production rate-limit verification/recovery and shared production rate-limit storage remain outstanding.
storage, and account recovery. Deployment instructions and sync behavior are in docs/DEPLOYMENT.md. Deployment instructions and sync behavior are in docs/DEPLOYMENT.md.
The current server binds only to loopback and runs without debug mode. The local server binds only to loopback; production runs behind the Dokku HTTPS proxy.
Users will upload FIT files or connect Garmin by authenticating locally with Users will upload FIT files or connect Garmin by authenticating locally with
`python-garminconnect` and uploading their exported session tokens. The server `python-garminconnect` and uploading their exported session tokens. The server
+20 -2
View File
@@ -12,7 +12,8 @@ key separately from database backups; losing it requires Garmin reconnection.
Push to Gitea, then deploy with `dokku git:sync --build stride Push to Gitea, then deploy with `dokku git:sync --build stride
https://gitea.peterstockings.com/peterstockings/Stride.git main` on the server. https://gitea.peterstockings.com/peterstockings/Stride.git main` on the server.
Enable HTTPS using `dokku letsencrypt:enable stride`. Map the web port with `dokku ports:set stride http:80:8000`, then enable HTTPS
using `dokku letsencrypt:enable stride`.
## Sync ## Sync
@@ -42,4 +43,21 @@ implemented. For a larger public deployment configure shared rate-limit storage.
Local automated suite: 39 passing tests, including manual/scheduled jobs, Local automated suite: 39 passing tests, including manual/scheduled jobs,
encryption, retry/authentication failure, locking, CSRF, and access control. encryption, retry/authentication failure, locking, CSRF, and access control.
Live deployment and Garmin results will be recorded after verification. Live verification on 2026-10-01:
- Built and deployed on Dokku 0.38.23; all PostgreSQL migrations succeeded.
- HTTPS certificate issued; external `/health` returned HTTP 200 and `status: ok`.
- Migrated the existing local account and 18 activities, preserving its password hash.
- Reused the local Garmin session on the Linux server, saved it encrypted, and
imported one new activity (19 total).
- Submitted a manual sync to the public HTTPS endpoint with an authenticated
session, CSRF token, and same-origin Referer. The background worker completed it.
- Moved `next_sync` into the past with `pending=false` and scheduling enabled.
The running worker picked it up automatically and completed the scheduled run.
This exercises the schedule due check without waiting an hour.
- Both repeat syncs imported zero duplicates and reported zero failures.
- Authenticated dashboard returned 200; anonymous private activity access returned 404.
- Production uses one web container (two Gunicorn processes) and one worker;
hourly scheduling remains enabled. The local session copy should no longer be
used concurrently with the server.