Versioning

The full version system: gateway releases, config_version, embedded dataset versions, and documentation versions.

Versioning

Quayel has four independent version layers. Understanding them is key to operating the gateway safely — every access log line records which gateway, which config, and which data it ran with.

LayerWhat it versionsWhere it livesExample
Gateway releaseThe binary / codeCargo.toml, Docker tag0.1.0, quayel/quayel-gateway:0.1.0
Config versionOne config.json revisionconfig_version field2026-01-15-001
Dataset versionsEmbedded IP intelligence datasrc/data/ at build timeDB-IP 2026-01, registry entries
Docs versionsThis documentationURL prefixes + version switcherv0.1 (latest)

Gateway releases

The gateway binary follows semantic versioning (MAJOR.MINOR.PATCH) via Cargo.toml:

  • MAJOR — breaking config schema changes (fields removed, enums changed, defaults changed)
  • MINOR — new plugins, new config fields, new condition paths (backward compatible)
  • PATCH — bug fixes, embedded data refreshes, performance work

Release artifacts:

  • Binary: target/release/quayel-gateway (strip debug symbols before shipping)
  • Docker: quayel/quayel-gateway:<version>
A dataset-only refresh (new MMDB / CIDR lists, no code change) ships as a PATCH release — but always record which dataset vintages went into the build (see below).

The config_version system

Every config.json must declare a config_version. It is a free-form string that identifies one revision of the config — the gateway never parses it, it only tracks and logs it.

{
  "gateway_id": "gw-prod-01",
  "config_version": "2026-01-15-001",
  ...
}

Rules

  1. Required. Configs without config_version are rejected at startup.
  2. Bump it on every change. This is the whole point: config revisions must be distinguishable.
  3. Recommended format: YYYY-MM-DD-NNN — date plus a per-day sequence number (2026-01-15-001, 2026-01-15-002, …). Simple counters ("1", "2") also work.
  4. Never reuse a version string for different content.

Why it matters

config_version is stamped into every JSONL access log line, so at any moment you can answer "which config produced this traffic?" during an incident or audit:

{
  "timestamp": "2026-01-15T10:30:45.123456789+00:00",
  "gateway_id": "gw-prod-01",
  "config_version": "2026-01-15-001",
  "request_id": "a1b2c3d4-..."
}

Hot reload and version transitions

The gateway hot-reloads its config — no restart, no dropped connections. The config watcher periodically hashes the file (SHA-256); when it changes:

  1. The new config is validated (parse + schema checks) and compiled (conditions, regexes, …)
  2. If validation or compilation fails, the gateway keeps the current config and retries on the next cycle — a broken config file can never take the gateway down
  3. On success, the compiled config is atomically swapped in (ArcSwap) and the transition is logged with both versions:
Config hot-reloaded successfully  old_version=2026-01-15-001  new_version=2026-01-15-002

Because every log line carries config_version, you can split traffic analysis across a reload boundary with a one-line jq filter:

jq 'select(.config_version == "2026-01-15-002")' access.jsonl
Auto-SSL domains are also updated on hot reload — adding a domain to the config only updates the allowed list; the certificate itself is provisioned on the next TLS handshake for that domain.

Dataset versions

IP intelligence data is compiled into the binary, so a dataset version = the vintage of src/data/ at build time. The gateway has no runtime data refresh.

What is versioned

DatasetVersioningVintage marker
dbip-city-lite.mmdbDB-IP monthly releaseFilename date, e.g. dbip-city-lite-2026-01
dbip-asn-lite.mmdbDB-IP monthly releaseFilename date
dbip-country.mmdbDB-IP monthly releaseFilename date
vpn.txtX4BNet, refreshed daily upstreamDate of download
tor.txtTor Project, refreshed hourly upstreamDate of download
cloudflare.txtCloudflare published rangesDate of download
hosting-asns.txtbad-asn-listDate of download
provider-asns.txtVersioned in the gateway repoGit history — one line per provider
proxy.txtFireHOL (empty by default)Date of download

The provider ASN registry

provider-asns.txt is the only dataset that is a living registry in the repo. It maps ASN → provider label (47583|Hostinger), driving ip.is_datacenter and ip.provider. Adding a provider is a one-line change followed by a rebuild; each entry is effectively versioned by the git commit that introduced it.

Recording dataset vintages

When cutting a gateway release, record the dataset vintages in the release notes, e.g.:

quayel-gateway 0.1.1 — data refresh
  dbip-city-lite    2026-02
  dbip-asn-lite     2026-02
  dbip-country      2026-02
  vpn.txt           2026-02-10
  tor.txt           2026-02-10
  provider-asns     git 8f3a2c1 (38 ASNs)

See Data Sources — Updating embedded data for the refresh procedure and the recommended update schedule.

Documentation versions

This documentation site has a built-in version system.

How it works

  • Unversioned URLs are always the LATEST docs. /quayel-gateway/getting-started tracks the current gateway release line.
  • Archived versions are snapshots served under a version prefix: /quayel-gateway/v0.1/getting-started is frozen at the moment v0.1 was the latest.
  • A version switcher appears at the top of the left sidebar on every /quayel-gateway page. It rewrites the current page's path between version prefixes, so you land on the same page in the other version.

Where versions live

PieceFile
Version list & labelsapp/app.config.ts → quayel.versions
Switcher UIapp/components/DocsVersionSelect.vue
Latest docscontent/quayel-gateway/**
Archived snapshotscontent/quayel-gateway/vX.Y/**
// app/app.config.ts
quayel: {
  versions: [
    { label: 'v0.1 (latest)', base: '/quayel-gateway', latest: true },
    { label: 'v0.1', base: '/quayel-gateway/v0.1', archived: true },
  ],
},

Cutting a new docs version

When a new gateway release line ships (say v0.2):

Snapshot the current docs

Copy the current pages into a versioned folder (the snapshot is never edited again):

cp -r content/quayel-gateway content/quayel-gateway/v0.1
# remove the section metadata from the snapshot if desired

Update the version list

In app/app.config.ts, add the archived entry and relabel latest:

quayel: {
  versions: [
    { label: 'v0.2 (latest)', base: '/quayel-gateway', latest: true },
    { label: 'v0.1', base: '/quayel-gateway/v0.1', archived: true },
  ],
},

Write the new docs

Edit the unversioned content/quayel-gateway/** pages for v0.2 changes. Archived snapshots stay untouched.

Version policy for docs

  • Docs are versioned per gateway release line (v0.1, v0.2, …), not per patch.
  • The unversioned docs always describe the latest release; never edit archived snapshots except for critical corrections.
  • Cross-version links should use unversioned URLs (they resolve to latest).

Quick reference

QuestionAnswer
Which binary am I running?Release version (Cargo.toml / Docker tag)
Which config produced this log line?.config_version in the JSONL line
Which IP data does this build embed?Dataset vintages recorded in the release notes
Which docs match my gateway?Use the version switcher; unversioned = latest
Did my config reload take effect?Stderr: Config hot-reloaded successfully old_version=… new_version=…
Copyright © 2026