Remove upgrade and older-build text from the README (closes #520) #521
@@ -465,10 +465,7 @@ idle timestamp is rewritten at most once per tenth of the idle window rather
|
|||||||
than on every request, which means a session may expire up to 10% early relative
|
than on every request, which means a session may expire up to 10% early relative
|
||||||
to the user's true last request, but never late.
|
to the user's true last request, but never late.
|
||||||
|
|
||||||
Both clocks are anchored by timestamps stored in the session cookie. Sessions
|
Both clocks are anchored by timestamps stored in the session cookie.
|
||||||
issued before this feature existed carry neither, so they are treated as
|
|
||||||
expired: upgrading to a build that has it logs every existing session out once,
|
|
||||||
and those users sign in again.
|
|
||||||
|
|
||||||
#### Invalid values abort startup
|
#### Invalid values abort startup
|
||||||
|
|
||||||
@@ -702,11 +699,11 @@ app as that user.
|
|||||||
`webhooker.db` holds target configuration in plaintext — bearer tokens, API
|
`webhooker.db` holds target configuration in plaintext — bearer tokens, API
|
||||||
keys, Slack webhook URLs — along with the session encryption key, so webhooker
|
keys, Slack webhook URLs — along with the session encryption key, so webhooker
|
||||||
creates every SQLite file it owns `0600`: each database and both of its `-wal`
|
creates every SQLite file it owns `0600`: each database and both of its `-wal`
|
||||||
and `-shm` sidecars, across all three tiers. Files an earlier build left `0644`
|
and `-shm` sidecars, across all three tiers. Any of them found at another mode
|
||||||
are tightened when they are opened. The directory's `0750` is defence in depth —
|
is set to `0600` when the database is opened. The directory's `0750` is defence
|
||||||
it stops other local users listing the directory and learning your webhook UUIDs
|
in depth — it stops other local users listing the directory and learning your
|
||||||
from the `events-{uuid}.db` filenames — not the barrier protecting the
|
webhook UUIDs from the `events-{uuid}.db` filenames — not the barrier protecting
|
||||||
credentials.
|
the credentials.
|
||||||
|
|
||||||
### Running under upaas
|
### Running under upaas
|
||||||
|
|
||||||
@@ -918,7 +915,7 @@ replaces the `max-age` it stored, so to end the policy sooner, set a short
|
|||||||
`HSTS_MAX_AGE` such as `1s` and keep it until returning browsers have picked it
|
`HSTS_MAX_AGE` such as `1s` and keep it until returning browsers have picked it
|
||||||
up, or have a reverse proxy send `max-age=0`.
|
up, or have a reverse proxy send `max-age=0`.
|
||||||
|
|
||||||
## Backup, Restore, and Upgrades
|
## Backup and Restore
|
||||||
|
|
||||||
### What to back up
|
### What to back up
|
||||||
|
|
||||||
@@ -1071,60 +1068,14 @@ beside it, or wait until there are none.
|
|||||||
|
|
||||||
4. Start the service. The container gives the directory and the restored files
|
4. Start the service. The container gives the directory and the restored files
|
||||||
to the `webhooker` user before the app starts, whoever restored them (see
|
to the `webhooker` user before the app starts, whoever restored them (see
|
||||||
[Running with Docker](#running-with-docker)). Each restored database gets any
|
[Running with Docker](#running-with-docker)).
|
||||||
of its SQL migrations it has not had as it is opened (see
|
|
||||||
[Upgrades](#upgrades)).
|
|
||||||
|
|
||||||
### Upgrades
|
|
||||||
|
|
||||||
**Back up before every upgrade.** Each kind of database file has its schema in
|
|
||||||
SQL files built into the binary, one directory per kind under
|
|
||||||
`internal/db/migrations/`. In each, `000_migration.sql` creates the
|
|
||||||
`schema_migrations` table, which records the number of every file the database
|
|
||||||
has had, and `001_schema.sql` holds the whole schema. Opening a database runs,
|
|
||||||
in one transaction, every file in its directory that `schema_migrations` does
|
|
||||||
not list:
|
|
||||||
|
|
||||||
- `main/` for the main database, on connect — settings, users, API keys,
|
|
||||||
webhooks, entrypoints and targets
|
|
||||||
- `events/` for each event database, when it is lazily opened — events,
|
|
||||||
deliveries, delivery results and their running totals
|
|
||||||
- `archive/` for each archive database, on every open and reopen
|
|
||||||
|
|
||||||
There are no down migrations.
|
|
||||||
|
|
||||||
Upgrade procedure:
|
|
||||||
|
|
||||||
1. Stop the service.
|
|
||||||
2. Back up `DATA_DIR` using one of the procedures above.
|
|
||||||
3. Pull the new image and start it.
|
|
||||||
4. Confirm `database migrations completed` in the logs before putting traffic
|
|
||||||
back on it.
|
|
||||||
5. Confirm the new build is the one running:
|
|
||||||
`curl -s http://host:8080/.well-known/healthcheck` reports the version it was
|
|
||||||
stamped with (see [Version stamping](#version-stamping)).
|
|
||||||
|
|
||||||
**Upgrading past the introduction of `BIND_ADDRESS`:** earlier versions always
|
|
||||||
bound every interface. **Container deployments are unaffected** — the image
|
|
||||||
ships `ENV BIND_ADDRESS=0.0.0.0`, so a `docker run` or Compose service that
|
|
||||||
worked before still works with nothing changed.
|
|
||||||
|
|
||||||
A **bare binary** is the case that changes: the listener now binds `127.0.0.1`
|
|
||||||
unless `BIND_ADDRESS` says otherwise, so a deployment that relied on reaching it
|
|
||||||
from another host becomes unreachable until it sets the address the proxy
|
|
||||||
connects to. Check the `bindAddress` field of the startup log to see what a
|
|
||||||
running process bound. See [Bind address](#bind-address).
|
|
||||||
|
|
||||||
**Downgrade is unsupported.** Once a newer binary has migrated the files there
|
|
||||||
is no way to move them back. The only supported way back to an older version is
|
|
||||||
restoring the pre-upgrade backup, which discards everything received since that
|
|
||||||
backup was taken.
|
|
||||||
|
|
||||||
### Version stamping
|
### Version stamping
|
||||||
|
|
||||||
The binary reports its version at `/.well-known/healthcheck` (the `version`
|
The binary reports its version at `/.well-known/healthcheck` (the `version`
|
||||||
field), in the UI footer, and in the startup log line (`msg=starting`,
|
field), in the UI footer, and in the startup log line (`msg=starting`,
|
||||||
`version=...`). It is also the Sentry release name, as `webhooker-{version}`.
|
`version=...`). It is also the Sentry release name, as `webhooker-{version}`.
|
||||||
|
`curl -s http://host:8080/.well-known/healthcheck` shows which build is running.
|
||||||
The value is stamped in at build time by the linker; it is not read from a file
|
The value is stamped in at build time by the linker; it is not read from a file
|
||||||
at runtime, so it identifies the build itself.
|
at runtime, so it identifies the build itself.
|
||||||
|
|
||||||
@@ -1583,8 +1534,7 @@ The cap is not arbitrary: the reaper computes its cutoff as a `time.Duration`,
|
|||||||
an int64 nanosecond count, and a longer period overflows it. An overflowed
|
an int64 nanosecond count, and a longer period overflows it. An overflowed
|
||||||
cutoff lands in the future, where it matches every row, so the sweep would
|
cutoff lands in the future, where it matches every row, so the sweep would
|
||||||
delete every event the webhook has instead of none. The reaper also clamps the
|
delete every event the webhook has instead of none. The reaper also clamps the
|
||||||
value it is given, so a row written by an older version cannot trigger that
|
value it reads to the cap, so no stored value can trigger that either.
|
||||||
either.
|
|
||||||
|
|
||||||
#### Entrypoint
|
#### Entrypoint
|
||||||
|
|
||||||
@@ -1967,7 +1917,7 @@ and application state:
|
|||||||
- **APIKeys** — programmatic access credentials
|
- **APIKeys** — programmatic access credentials
|
||||||
|
|
||||||
On first startup the main database is created from its SQL files (see
|
On first startup the main database is created from its SQL files (see
|
||||||
[Upgrades](#upgrades)), a session encryption key is generated and stored, and an
|
[Schema](#schema)), a session encryption key is generated and stored, and an
|
||||||
`admin` user is created.
|
`admin` user is created.
|
||||||
|
|
||||||
**Per-Webhook Event Databases** (`{DATA_DIR}/events-{webhook_uuid}.db`) — each
|
**Per-Webhook Event Databases** (`{DATA_DIR}/events-{webhook_uuid}.db`) — each
|
||||||
@@ -2164,6 +2114,21 @@ The database uses the
|
|||||||
though CGO is required at build time due to the transitive `mattn/go-sqlite3`
|
though CGO is required at build time due to the transitive `mattn/go-sqlite3`
|
||||||
dependency from `gorm.io/driver/sqlite`.
|
dependency from `gorm.io/driver/sqlite`.
|
||||||
|
|
||||||
|
#### Schema
|
||||||
|
|
||||||
|
Each kind of database file has its schema in SQL files built into the binary,
|
||||||
|
one directory per kind under `internal/db/migrations/`. In each,
|
||||||
|
`000_migration.sql` creates the `schema_migrations` table, which records the
|
||||||
|
number of every file the database has had, and `001_schema.sql` holds the whole
|
||||||
|
schema. Opening a database runs, in one transaction, every file in its directory
|
||||||
|
that `schema_migrations` does not list:
|
||||||
|
|
||||||
|
- `main/` for the main database, on connect — settings, users, API keys,
|
||||||
|
webhooks, entrypoints and targets
|
||||||
|
- `events/` for each event database, when it is lazily opened — events,
|
||||||
|
deliveries, delivery results and their running totals
|
||||||
|
- `archive/` for each archive database, on every open and reopen
|
||||||
|
|
||||||
### Request Flow
|
### Request Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user