Skip to content
bnemaPublic

About

Self-hosted container deployment. Push an image, declare an app, deploy it.

Topics

Resources

Stars

14 stars

Watchers

2 watching

Forks

Repository files navigation

Gordon

License: GPL-3.0

Self-hosted container deployment. Push an image, declare an app, deploy it.


What is Gordon?

Gordon is a private image container registry, an app runtime, and a reverse proxy for your VPS.

The flow is explicit: you build an image locally, push it to your registry then declare the app in a standalone TOML file, apply it, deploy and it's live.

Quick Start

# Install the latest stable release to ~/.local/bin
curl -fsSL https://bnema.dev/gordon/install | sh

# Start the server (restart your shell first if the installer updated PATH)
gordon serve

See the installation guide for more.

Config is created at ~/.config/gordon/gordon.toml. See the Getting Started guide for full setup.

Deploy with the CLI

Example of the flow :

# Push the image (OCI transfer only, never deploys)
gordon images push myapp --build --remote prod

# Declare the app (blog.toml references the pushed tag)
gordon apps apply --file blog.toml --remote prod

# Activate it
gordon apps deploy blog --remote prod

# Check status
gordon daemon status
gordon apps status blog --remote prod

Minimal app file (blog.toml):

name = "blog"

[services.web]
image = "gordon.mydomain.com/myapp:v1.2.0"

[[services.web.http]]
host = "blog.mydomain.com"
port = 3000

Manage lifecycle and secrets — all from the command line:

gordon apps restart blog --remote prod   # Restart from pinned digests
gordon apps stop blog --remote prod      # Stop, preserve all data
gordon apps secrets set blog --service web DATABASE_URL=... --remote prod

Deploy from CI/CD

Push to Gordon's registry from any CI pipeline, then apply and deploy with the CLI. Push never triggers a deploy by itself.

GitHub Actions

- uses: bnema/gordon/.github/actions/deploy@main
  with:
    registry: registry.mydomain.com
    username: ${{ secrets.GORDON_USERNAME }}
    password: ${{ secrets.GORDON_TOKEN }}

See the Deploy Action README for multi-platform builds, monorepo support, and all available options.

Docker CLI + Gordon CLI

docker login gordon.mydomain.com
docker build -t gordon.mydomain.com/myapp:v1.0.0 .
docker push gordon.mydomain.com/myapp:v1.0.0
# Then, with the Gordon binary:
gordon apps apply --file blog.toml --remote prod
gordon apps deploy blog --remote prod

CLI Commands

Server

Command Description
gordon serve Start the Gordon server
gordon daemon status Show server and app fleet status
gordon daemon logs Show Gordon process logs
gordon daemon reload Reload installation configuration
gordon daemon config show Display installation configuration

Applications

Command Description
gordon apps apply --file FILE Validate and persist an app manifest
gordon apps deploy APP Activate an app revision
gordon apps list List applications
gordon apps show APP Show desired and active state
gordon apps status APP Show effective vs observed state
gordon apps logs APP Show logs for an app service
gordon apps restart APP Restart from pinned digests
gordon apps stop APP Stop, preserve all data
gordon apps start APP Start a stopped app
gordon apps remove APP Remove workloads (volumes/secrets retained)

Images & Registry

Command Description
gordon images push [image] Tag and push an image (never deploys)
gordon images list List runtime and registry images
gordon images prune Clean up dangling images and old tags
gordon images tags <repo> List registry tags for a repository

Secrets

Command Description
gordon apps secrets list APP List app secret names
gordon apps secrets set APP --service SVC KEY=VAL Set app secret values

Remotes & Auth

Command Description
gordon remotes list List remote Gordon endpoints
gordon remotes add <name> <url> Add a remote
gordon remotes use <name> Set the active remote
gordon auth login Authenticate to a remote
gordon auth token generate Generate a JWT token

Features

  • Private Docker/Podman registry on your VPS
  • Declarative apps: one TOML file per app, explicit apply then deploy
  • Domain-to-container routing through a smart TCP edge reverse proxy
  • Sequential service replacement (withdraw traffic, replace one generation, verify readiness, republish)
  • Remote CLI management (daemon is the sole writer)
  • Declarative per-service volumes, retained across lifecycle operations
  • Per-service secrets in pass, app-wide public env in the manifest
  • Per-app private networks plus opt-in shared networks
  • Single binary

Note

Gordon exposes public traffic through entrypoints such as [entrypoints.edge] with protocol = "smart_tcp". It can terminate TLS via static certificates, public ACME certificates, or its internal CA. Cloudflare and upstream reverse proxies are optional deployment choices, not requirements. Use Gordon's ownership-aware volume commands; runtime commands such as docker volume prune bypass Gordon's retention checks.

Documentation

Full documentation at bnema.dev/gordon

  • Docs — Installation, configuration, CLI reference
  • Wiki — Tutorials, guides, and examples

Community

License

GPL-3.0 — Use freely, contribute back.

About

Self-hosted container deployment. Push an image, declare an app, deploy it.

Topics

Resources

Stars

14 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages