Skip to main content

Deployment

Lumio uses release-driven deployment. Container images are built and pushed only when a GitHub Release is published -- there are no automatic image builds on branch pushes. The workflow lives in .github/workflows/release-images.yml.

Release Strategy

Every deploy starts with a GitHub Release. The release tag encodes which app to deploy and the version:

{app}@{version}

The workflow parses the tag, determines the target app, runs Bazel tests, builds the image, and pushes it to the container registry.

How to Deploy

  1. Go to GitHub Releases for the repository.
  2. Click Draft a new release.
  3. Create a tag following the {app}@{version} format.
  4. Mark the release as a pre-release if the image should receive beta tags instead of latest.
  5. Publish the release.

Tag examples:

api@2026.5.3
twitch-bot@2026.5.1
web@2026.5.2
discord-bot@2026.5.1

Image Tags

The workflow generates multiple tags per image based on whether the release is marked as a pre-release.

Production (stable release)

TagExampleDescription
{version}2026.5.3Exact version
{major.minor}2026.5Floating minor tag
latestlatestMost recent stable release
{short_sha}a1b2c3d7-character commit SHA
{full_sha}a1b2c3d...Full 40-character commit SHA

Pre-release (beta)

TagExampleDescription
{version}2026.5.3-beta.1Exact pre-release version
betabetaFloating beta tag
{short_sha}a1b2c3d7-character commit SHA
{full_sha}a1b2c3d...Full 40-character commit SHA

A version string containing beta, alpha, or rc is also treated as a pre-release regardless of the GitHub Release checkbox.

Deployable Apps

AppTypeTag PrefixBuild Tool
apiRust binaryapi@Bazel
bot-module-workerRust binarybot-module-worker@Bazel
twitch-botRust binarytwitch-bot@Bazel
youtube-botRust binaryyoutube-bot@Bazel
kick-botRust binarykick-bot@Bazel
trovo-botRust binarytrovo-bot@Bazel
discord-botRust binarydiscord-bot@Bazel
webNext.jsweb@Docker
adminNext.jsadmin@Docker
idNext.jsid@Docker

Rust binaries are built with Bazel (bazel run //apps/{app}:{app}_push) and produce minimal Alpine-based images via rules_img. Next.js apps are built with traditional Dockerfiles (docker/{app}.Dockerfile).

Bulk Deploys

Three special tag prefixes deploy multiple apps at once:

Tag PrefixDeploys
all@{version}All 10 apps (7 Rust + 3 Next.js)
all-rust@{version}All 7 Rust apps
all-web@{version}All 3 Next.js apps

Example: publishing a release tagged all@2026.5.3 builds and pushes every app image.

Manual Dispatch

For emergency deploys or rebuilds without creating a release, the workflow supports workflow_dispatch with two inputs:

InputDescription
appWhich app to deploy (dropdown: all, all-rust, all-web, or any individual app)
tagThe image tag to apply

This is useful when the release flow is unavailable or when retagging an existing build.

Container Registry

All images are pushed to GitHub Container Registry (GHCR):

ghcr.io/{org}/lumio/{app}

For example:

ghcr.io/zaflun/lumio/api:2026.5.3
ghcr.io/zaflun/lumio/twitch-bot:latest
ghcr.io/zaflun/lumio/web:beta

Authentication uses the GITHUB_TOKEN provided by GitHub Actions with packages: write permission.

Environments

Branch and tag mapping determines which environment receives a deploy:

Branch / TagEnvironment
nextStaging
mainProduction preview
Release tag (e.g., api@2026.5.3)Production

See the Installation guide for the full domain table per environment.

Security Audit

A nightly security audit runs via .github/workflows/security-audit.yml (cron: 0 3 * * * UTC). It scans both dependency ecosystems and reports to Discord:

CheckToolScope
Rust dependenciescargo auditAll advisories
npm dependenciespnpm auditHigh and critical severity

Alert flow:

  • Individual vulnerability alerts fire immediately via Discord webhook (DISCORD_SECURITY_WEBHOOK_URL).
  • A daily summary always posts -- either "All clear" (green) or "Action required" (yellow) with vulnerability counts.

The workflow also supports manual workflow_dispatch for on-demand scans.