Document temporary VPS staging plan
This commit is contained in:
+13
-1
@@ -36,7 +36,7 @@ Staging currently exercises the PostgreSQL → API → frontend path with synthe
|
||||
### SolidJS frontend
|
||||
|
||||
- Queries the backend using the same origin in production builds.
|
||||
- Provides Stations, City Analysis, Faktiskā, Latvia overview, Database, HARMONIE, and LVGMC forecast workspaces. A separate Ūdens temperatūra production workspace is planned.
|
||||
- Provides Stations, City Analysis, Faktiskā, Ūdens temperatūra, Latvia overview, Database, HARMONIE, and LVGMC forecast workspaces.
|
||||
- Uses HTML canvas for broadcast maps and PNG export.
|
||||
- Uses normalized transparent PNG assets for weather symbols; the internal letter codes remain stable identifiers and are not rendered as text or emoji.
|
||||
|
||||
@@ -92,3 +92,15 @@ Monda Regular and Bold are bundled locally and used by the interface and generat
|
||||
- Production monitoring, backups, incident handling, or a reviewed security boundary.
|
||||
|
||||
See `UPDATE_ROADMAP.md` before considering workplace deployment.
|
||||
|
||||
## Proposed temporary public-testing edge
|
||||
|
||||
WeatherTool has not yet been deployed publicly. The proposed month-long user-acceptance environment adds a removable edge layer without changing the application into the authentication authority:
|
||||
|
||||
```text
|
||||
Cloudflare -> VPS Nginx -> Authelia authorization -> WeatherTool -> PostgreSQL
|
||||
```
|
||||
|
||||
Rocky remains the trusted build and verification host. The VPS receives a commit-addressed immutable image and release metadata rather than pulling and building the development repository. WeatherTool, its database, and Authelia must use a dedicated Compose project, private network, storage paths, and loopback-only upstream port so the existing VPS services remain untouched.
|
||||
|
||||
See `VPS_STAGING_PLAN.md` for the proposed topology and release procedure.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|---|---|---|
|
||||
| Windows | Source editing and Git workflow only | Not applicable |
|
||||
| Rocky Linux | Docker development and production-like staging | `http://192.168.1.101:9190` |
|
||||
| Future VPS | Planned deployment environment | Not provisioned yet |
|
||||
| Temporary VPS | Proposed month-long user-acceptance staging behind Cloudflare, Nginx, and Authelia | Not provisioned; hostname pending |
|
||||
| Workplace production | Out of scope until reviewed and approved | Not documented here |
|
||||
|
||||
Rocky checkout:
|
||||
@@ -96,9 +96,10 @@ At minimum, verify:
|
||||
3. The home navigation loads.
|
||||
4. City Analysis can query synthetic observations.
|
||||
5. Each map resolution renders and downloads.
|
||||
6. Faktiskā automatically loads the latest fixed-station temperatures, allows overrides, assigns font symbols, supports exceptions, and downloads a 3840×1440 PNG.
|
||||
6. Faktiskā automatically loads the latest fixed-station temperatures, allows overrides, assigns normalized image symbols, supports exceptions, and downloads a 3840×1440 PNG.
|
||||
7. Faktiskā symbols remain automatically attached to their corresponding temperature badges when several different image assets are tested.
|
||||
8. Browser developer tools show no new runtime errors.
|
||||
8. Ūdens temperatūra accepts all six manual ranges and exports both 1920×1080 and 3840×1440 PNGs.
|
||||
9. Browser developer tools show no new runtime errors.
|
||||
|
||||
Known limitation: direct browser refreshes on newer client-side routes such as `/faktiska` can return 404 because the backend static-route list does not yet provide a general SPA fallback. Navigate from the home page until that backend behavior is fixed.
|
||||
|
||||
@@ -108,8 +109,18 @@ Prefer a normal Git revert rather than manually copying old files:
|
||||
|
||||
1. Identify the faulty commit with `git log --oneline`.
|
||||
2. On the development checkout, run `git revert <commit>`.
|
||||
3. Push the revert and build and test it on Rocky.
|
||||
4. Push the revert commit.
|
||||
5. Pull it on Rocky and run the appropriate frontend-only or full-stack deployment command.
|
||||
3. Build and test the revert on Rocky.
|
||||
4. Push the verified revert commit.
|
||||
5. Pull it into the Rocky staging checkout and run the appropriate frontend-only or full-stack deployment command.
|
||||
|
||||
Database rollback is a separate operation and must not be inferred from a source rollback. Database backup and restore procedures are not yet defined.
|
||||
|
||||
## Proposed VPS release boundary
|
||||
|
||||
The temporary VPS must not become another development checkout. The proposed release flow is:
|
||||
|
||||
```text
|
||||
Windows source and Git -> Rocky build and verification -> immutable image + checksum -> VPS deployment
|
||||
```
|
||||
|
||||
Releases are manual during user acceptance and are identified by the source commit SHA. The VPS keeps WeatherTool in its own `/srv/weathertool` tree, publishes the application only to a loopback port, and relies on Nginx plus Authelia at the public boundary. See `VPS_STAGING_PLAN.md` before provisioning or changing the VPS.
|
||||
|
||||
@@ -13,6 +13,7 @@ This directory contains the working documentation for the WeatherTool modernizat
|
||||
- Faktiskā symbol placement is automatic after manual image selection and is anchored to each rendered temperature badge.
|
||||
- The first **Ūdens temperatūra** workspace is implemented with manual Latvian-named fields and required 1920×1080 and 3840×1440 exports; visual calibration remains in progress.
|
||||
- Confirmed local Monda Regular/Bold files provide interface and generated-graphic typography; weather symbols use normalized transparent image assets.
|
||||
- The next proposed environment is a temporary, isolated VPS user-acceptance deployment built on Rocky, protected by Cloudflare, Nginx, and removable Authelia authentication. It has not yet been provisioned.
|
||||
- This is not yet approved or hardened for workplace production.
|
||||
|
||||
## Documents
|
||||
@@ -22,6 +23,7 @@ This directory contains the working documentation for the WeatherTool modernizat
|
||||
- [Product workflows](PRODUCT_WORKFLOWS.md) — the intended purpose and current status of each visible workspace.
|
||||
- [Update roadmap](UPDATE_ROADMAP.md) — phased technical, security, dependency, testing, and UI work.
|
||||
- [Third-party notices](THIRD_PARTY_NOTICES.md) — licenses and attribution for adapted interface components.
|
||||
- [Temporary VPS staging plan](VPS_STAGING_PLAN.md) — proposed isolation, authentication, release, backup, verification, and rollback model for external user testing.
|
||||
|
||||
## Documentation rules
|
||||
|
||||
|
||||
+19
-1
@@ -7,7 +7,8 @@ This document tracks proposed WeatherTool improvements. Work should be delivered
|
||||
- **Windows development:** source editing and Git workflow only; Docker runtime testing is performed on Rocky.
|
||||
- **Rocky staging:** production-like Docker deployment at `http://192.168.1.101:9190`.
|
||||
- **Git over SSH:** Windows pushes reviewed commits to a private bare repository on Rocky; the Rocky staging checkout pulls those commits and rebuilds.
|
||||
- **Production:** remains separate until changes are reviewed, tested, and explicitly approved for workplace use.
|
||||
- **Temporary VPS staging:** proposed month-long external user acceptance behind Cloudflare, Nginx, and Authelia; not yet provisioned.
|
||||
- **Workplace production:** remains separate until changes are reviewed, tested, and explicitly approved for workplace use.
|
||||
|
||||
Do not synchronize `.env`, database directories, generated dependencies, build output, or provider credentials between machines.
|
||||
|
||||
@@ -140,6 +141,20 @@ Status: pending
|
||||
- [ ] Rehearse deployment and rollback using sanitized data.
|
||||
- [ ] Obtain technical and operational review before workplace rollout.
|
||||
|
||||
## Phase 8 — Temporary VPS user acceptance
|
||||
|
||||
Status: planned
|
||||
|
||||
- [x] Document the proposed isolated VPS topology and trusted Rocky-to-VPS release flow.
|
||||
- [ ] Choose the WeatherTool and Authelia hostnames and create their Cloudflare DNS records.
|
||||
- [ ] Record a read-only VPS inventory before provisioning and confirm ports, networks, storage, and capacity do not collide with existing services.
|
||||
- [ ] Provision a dedicated `/srv/weathertool` tree, Compose project, private network, database storage, and loopback-only application port.
|
||||
- [ ] Configure Authelia with one temporary shared account, Argon2id password storage, rate limiting, and temporary IP bans.
|
||||
- [ ] Add host-specific TLS certificates and Nginx authorization routing without weakening the existing Cloudflare-only firewall boundary.
|
||||
- [ ] Build and verify a commit-addressed immutable image on Rocky, then transfer its image archive and checksum to the VPS.
|
||||
- [ ] Verify authentication, direct-origin blocking, application health, generated PNG downloads, backups, logs, and rollback.
|
||||
- [ ] Run the month-long user test with manual releases and record feedback before any workplace-production decision.
|
||||
|
||||
## Known current limitations
|
||||
|
||||
- Staging uses synthetic PostgreSQL station data.
|
||||
@@ -165,3 +180,6 @@ Record completed work here by date and commit after the Git workflow is establis
|
||||
| 2026-08-19 | `5913217` | Add Valmiera to the deterministic Faktiskā development data | Yes |
|
||||
| 2026-08-19 | `632f377` | Arrange manual Faktiskā wind controls horizontally | Yes |
|
||||
| 2026-08-19 | `340c370`–`3aba9b4` | Anchor and visually calibrate manually selected Faktiskā symbols | Yes |
|
||||
| 2026-08-19 | `1868041`–`6c9290b` | Add Ūdens temperatūra, bundle and load Monda, fix overlay scaling, and center its locked nameplate | Yes |
|
||||
| 2026-08-19 | `0d641bd` | Replace runtime Daira glyph rendering with normalized transparent image assets | Yes |
|
||||
| 2026-08-20 | `754415a` | Match editable title/source overlays to production-safe right margins | Yes |
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
# Temporary VPS staging plan
|
||||
|
||||
Status: **Proposed; WeatherTool has not been provisioned on the VPS**
|
||||
|
||||
This document defines the next deployment stage for approximately one month of
|
||||
newsroom-user testing. It records the intended boundary before any VPS changes
|
||||
are made. The existing HOP/Adaco documentation was reviewed as an infrastructure
|
||||
reference; WeatherTool must remain independent from that application and all
|
||||
other VPS workloads.
|
||||
|
||||
## Objectives
|
||||
|
||||
- Keep Rocky Linux as the development, Docker-test, and trusted release-build
|
||||
environment.
|
||||
- Publish a committed WeatherTool revision for three invited testers through a
|
||||
separate Cloudflare-proxied hostname.
|
||||
- Protect the complete WeatherTool hostname with a self-hosted Authelia
|
||||
username/password portal during public testing.
|
||||
- Make releases traceable and reversible without giving the VPS access to the
|
||||
Rocky Git repository or the home network.
|
||||
- Keep removal of public authentication simple when the eventual workplace
|
||||
deployment is local-only.
|
||||
|
||||
This temporary environment is user-acceptance staging, not workplace
|
||||
production. It continues to use synthetic data until authorized provider
|
||||
credentials and the actual data contract are available.
|
||||
|
||||
## Reused VPS infrastructure boundary
|
||||
|
||||
The reviewed VPS documentation records an existing Ubuntu host with Nginx,
|
||||
Docker Compose, Cloudflare-restricted public HTTP/HTTPS, restored Cloudflare
|
||||
client addresses, Tailscale administration, log rotation, and unrelated live
|
||||
workloads. These shared host facilities may be reused, but existing virtual
|
||||
hosts, containers, networks, databases, firewall behavior, and service units
|
||||
must not be replaced or restarted merely to deploy WeatherTool.
|
||||
|
||||
Before provisioning, perform a read-only VPS inventory and confirm:
|
||||
|
||||
- free memory, swap, disk space, and current container resource usage;
|
||||
- current Nginx include and certificate layout;
|
||||
- Cloudflare trusted-address and UFW configuration;
|
||||
- an unused loopback application port;
|
||||
- the SSH/Tailscale administration and recovery path; and
|
||||
- sufficient backup capacity.
|
||||
|
||||
## Environment and trust flow
|
||||
|
||||
```text
|
||||
Windows source workspace
|
||||
-> commit and push over SSH
|
||||
Rocky bare repository and working checkout
|
||||
-> build, test, and visually accept the exact commit
|
||||
Rocky trusted release build
|
||||
-> export versioned image + SHA-256 checksum over authenticated SSH/Tailscale
|
||||
Temporary VPS
|
||||
-> verify and load image; never pull from the home Git host
|
||||
Cloudflare -> Nginx -> Authelia authorization -> WeatherTool
|
||||
```
|
||||
|
||||
The VPS receives a built release artifact, not a development checkout. It gets
|
||||
no credential or route for the Rocky Git repository, the private Forgejo
|
||||
instance, or the home LAN.
|
||||
|
||||
## VPS isolation layout
|
||||
|
||||
Proposed application root:
|
||||
|
||||
```text
|
||||
/srv/weathertool/
|
||||
compose.yml
|
||||
.env.staging # untracked, root-owned, mode 0600
|
||||
config/
|
||||
authelia/
|
||||
configuration.yml # no secret values committed
|
||||
users.yml # Argon2id hash; protected on the VPS
|
||||
data/
|
||||
postgres/
|
||||
authelia/
|
||||
backups/
|
||||
releases/
|
||||
```
|
||||
|
||||
WeatherTool will use:
|
||||
|
||||
- a unique Compose project name;
|
||||
- a private application network;
|
||||
- its own PostgreSQL service and persistent storage;
|
||||
- its own Authelia configuration and storage;
|
||||
- a loopback-only application binding, with the final port chosen after the
|
||||
VPS inventory; and
|
||||
- no shared Docker volumes, database, or application network with HOP or any
|
||||
other service.
|
||||
|
||||
Only Nginx may expose WeatherTool publicly. PostgreSQL and Authelia's internal
|
||||
service port must not be published to the internet. Docker port bindings must
|
||||
not be allowed to bypass the intended firewall boundary.
|
||||
|
||||
## Authentication boundary
|
||||
|
||||
Authelia is a removable reverse-proxy authentication layer; no WeatherTool
|
||||
route or data model will be changed to implement the temporary shared account.
|
||||
|
||||
Initial proposed policy:
|
||||
|
||||
- one generated shared test username and a random 20-24 character password;
|
||||
- password stored only as an Argon2id hash;
|
||||
- secrets and plaintext credentials excluded from Git, images, documentation,
|
||||
shell history where practical, and deployment logs;
|
||||
- approximately 12-hour authenticated sessions;
|
||||
- three failed attempts from one client address within two minutes results in
|
||||
a temporary 15-minute IP ban;
|
||||
- no permanent or username-wide three-attempt ban, because an attacker could
|
||||
otherwise lock out all users of the shared account;
|
||||
- generic login errors and retained, rotated authentication logs; and
|
||||
- a working logout route.
|
||||
|
||||
Nginx must ask Authelia to authorize every WeatherTool route. Client-address
|
||||
regulation is meaningful only when Nginx trusts `CF-Connecting-IP` exclusively
|
||||
from Cloudflare proxy networks and direct public origin traffic is rejected.
|
||||
|
||||
For a future local-only workplace deployment, remove the Nginx authorization
|
||||
include and Authelia service. The application remains unchanged.
|
||||
|
||||
## Domain, TLS, and Nginx
|
||||
|
||||
The WeatherTool hostname is not yet selected. Before DNS publication:
|
||||
|
||||
1. Add an isolated Nginx virtual host without changing existing hosts.
|
||||
2. Install a certificate valid for the exact WeatherTool/Authelia hostname or
|
||||
hostnames; do not assume an existing non-wildcard certificate covers them.
|
||||
3. Bind the upstream application to loopback only.
|
||||
4. Verify the application and Authelia privately.
|
||||
5. Create a proxied Cloudflare DNS record.
|
||||
6. Apply strict origin TLS for the WeatherTool hostname.
|
||||
7. Redirect HTTP to HTTPS and begin with a short staging HSTS lifetime such as
|
||||
3,600 seconds.
|
||||
8. Avoid caching authenticated HTML and API responses at Cloudflare.
|
||||
9. Confirm TLS, static assets, login, logout, API calls, PNG downloads, real
|
||||
client addresses, and direct-origin rejection.
|
||||
|
||||
Whether Authelia uses a dedicated `auth.<domain>` hostname or a subpath remains
|
||||
an explicit deployment decision. A dedicated hostname is conventional; a
|
||||
same-host subpath reduces DNS and certificate entries for this single app.
|
||||
|
||||
## Manual release procedure
|
||||
|
||||
Continuous deployment is deliberately out of scope for the first testing
|
||||
month. Each release requires an operator checkpoint.
|
||||
|
||||
1. Require a clean, committed source tree and record the full Git SHA.
|
||||
2. Push and deploy that commit on Rocky.
|
||||
3. Run the frontend build, available checks, and critical workflow smoke tests.
|
||||
4. Build a production-only application image on Rocky and tag it with the full
|
||||
Git SHA.
|
||||
5. Export/compress the image and create a SHA-256 checksum.
|
||||
6. Transfer the artifact and checksum to a temporary VPS release location over
|
||||
authenticated SSH/Tailscale.
|
||||
7. Verify the checksum before loading the image.
|
||||
8. Back up WeatherTool PostgreSQL before database-affecting releases.
|
||||
9. Select the new immutable image tag in the VPS environment configuration.
|
||||
10. Recreate only the affected WeatherTool service.
|
||||
11. Verify container health, loopback HTTP, Authelia, public HTTPS, APIs, and
|
||||
representative graphic exports.
|
||||
12. Record release time, Git SHA, image tag, checksum, backup, verification,
|
||||
operator, and rollback tag without recording secrets.
|
||||
13. Remove temporary transfer copies after acceptance and retain the previous
|
||||
compatible image for rollback.
|
||||
|
||||
Frontend-only source changes may still require a new immutable application
|
||||
image on the VPS. The existing Rocky bind-mounted frontend workflow is a
|
||||
development convenience, not the proposed VPS release model.
|
||||
|
||||
## Acceptance checklist
|
||||
|
||||
- Existing VPS workloads remain healthy and unchanged.
|
||||
- WeatherTool services use only their dedicated project/network/storage.
|
||||
- PostgreSQL is not publicly published.
|
||||
- Direct origin web access is rejected; Cloudflare HTTPS succeeds.
|
||||
- Unauthenticated requests reach the Authelia portal, not WeatherTool.
|
||||
- Valid login, session persistence, logout, throttling, and temporary ban
|
||||
recovery work.
|
||||
- `/`, City Analysis, Faktiskā, and Ūdens temperatūra work with synthetic data.
|
||||
- Required PNG dimensions and filenames remain correct after deployment.
|
||||
- Browser developer tools and container/Nginx/Authelia logs show no unexpected
|
||||
errors or secret values.
|
||||
- The preceding image can be selected without rebuilding it.
|
||||
|
||||
## Rollback and backup minimum
|
||||
|
||||
For an application-only fault, select the previous image tag and recreate only
|
||||
the WeatherTool application service. A source or image rollback does not undo a
|
||||
database migration; database-affecting releases require a matching backup and
|
||||
an explicit restore decision.
|
||||
|
||||
Proposed temporary-staging minimum:
|
||||
|
||||
- daily WeatherTool PostgreSQL backup;
|
||||
- pre-deployment backup before database-affecting changes;
|
||||
- seven daily backups retained initially;
|
||||
- at least one encrypted off-VPS copy once tester-entered data matters; and
|
||||
- a documented and tested restoration exercise.
|
||||
|
||||
## Decisions and prerequisites still open
|
||||
|
||||
- Final public hostname and Cloudflare zone.
|
||||
- Dedicated Authelia hostname versus same-host subpath.
|
||||
- Confirmed VPS capacity and unused loopback port.
|
||||
- Deployment account and whether normal releases use public SSH or Tailscale.
|
||||
- Final session and backup-retention values.
|
||||
- Secure operator-side generation and delivery of the shared credential.
|
||||
- A production Dockerfile/Compose definition validated independently from the
|
||||
Rocky development Compose file.
|
||||
- Health/readiness behavior suitable for automated release verification.
|
||||
|
||||
Reference in New Issue
Block a user