Deployment and releases
Retsu publishes one production image that can run migrations, the API, or one named worker.
Image
Published images use:
ghcr.io/karanbalani/retsu:YEAR.MONTH.RELEASE
For example:
docker pull ghcr.io/karanbalani/retsu:2026.7.1
docker run --rm ghcr.io/karanbalani/retsu:2026.7.1 --version
Every release also has a sha-<commit> tag. There is no latest tag, so deployments must choose an explicit version or commit.
Images are built for Linux AMD64 and ARM64. The runtime image:
- runs as user and group
65532; - contains the Retsu binary, required system libraries, and certificate authorities;
- has no shell or package manager;
- exposes API port
2424and worker management port24247; - uses
apias its default command.
Runtime roles
Use the same image for each role:
docker run --rm [settings] ghcr.io/karanbalani/retsu:2026.7.1 migrate
docker run --rm [settings] ghcr.io/karanbalani/retsu:2026.7.1 api
docker run --rm [settings] ghcr.io/karanbalani/retsu:2026.7.1 worker run queue expired-message-cleaner
docker run --rm [settings] ghcr.io/karanbalani/retsu:2026.7.1 worker run queue dead-letter-message-cleaner
docker run --rm [settings] ghcr.io/karanbalani/retsu:2026.7.1 worker run queue state-metrics-collector
Replace [settings] with environment variables, network settings, and port mappings for the deployment. At minimum, every role needs the PostgreSQL URL. Queue operations also need the distributed cache URL when that cache is enabled.
Example API settings:
docker run --rm \
--publish 2424:2424 \
--env RETSU_HTTP__BIND_ADDRESS=0.0.0.0 \
--env RETSU_DATABASE__URL=postgres://user:password@database:5432/retsu \
--env RETSU_CACHE__DISTRIBUTED__URL=redis://cache:6379 \
ghcr.io/karanbalani/retsu:2026.7.1 api
Use a secret manager instead of putting production credentials directly in a shell command.
Rollout order
- Run
migrateas a one-time job. - Start or update the API.
- Start each required worker as its own process.
- Check
/health/readybefore sending traffic or marking a worker ready. - Scrape
/metricsfrom the API and every worker.
Run migrations once per release rollout. The API and workers do not apply them automatically.
Each process has its own database pool. Each state collector leader also holds one dedicated database connection for its PostgreSQL lock.
Configuration
The image does not contain the repository's local YAML file. Provide RETSU_ environment variables or mount a YAML file and pass it explicitly:
retsu --config /etc/retsu.yaml api
See Configuration and Workers.
Creating a release
Maintainers create calendar-version tags from a clean local main that exactly matches origin/main:
just release-tag 2026.7.1
The command asks for confirmation and pushes the annotated v2026.7.1 tag.
The release workflow then:
- checks the tag format and confirms its commit belongs to
main; - builds and publishes the AMD64 and ARM64 images;
- attaches build provenance and a software bill of materials;
- publishes the version and commit tags without
latest; - creates a GitHub release with generated notes.