Document verified Dokku deployment and live sync results
This commit is contained in:
@@ -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
@@ -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.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user