Cariosan

Pulling from GHCR

Image tags, what's inside, and how to pin a version for production.

4 min readUpdated May 14, 2026

Cariosan's server is published as a Docker image to GitHub Container Registry at ghcr.io/cariosan/server. This page documents what's available, how to choose a tag, and what's inside the image.

Quick pull

terminal
docker pull ghcr.io/cariosan/server:latest

For production, pin a specific version so an upstream release doesn't change behavior under you:

terminal
docker pull ghcr.io/cariosan/server:v0.1.0

Tag policy

Tag patternPromiseUse when
latestLatest stable release. Updates when we ship.Local dev, evaluating Cariosan.
vX.Y.Z (e.g. v0.1.0)Exact semver release. Frozen forever.Production.
vX.Y (e.g. v0.1)Tracks the latest patch in that minor. Updates when we ship a v0.1.1.Production if you want auto-patch fixes without changing minors.
mainLatest commit on the main branch. Unstable. Compiles but may have unmerged-feature regressions.Never in production. CI experiments only.
pr-NNPer-pull-request preview build.Reviewing a PR locally.

Always prefer vX.Y.Z or vX.Y in production. latest is fine for development but means an unattended docker compose pull could land you on a new major version.

What's inside

The image is a multi-stage build that ends on a distroless base for a minimal attack surface.

  • Base image: gcr.io/distroless/static-debian12:nonroot
  • Architectures: linux/amd64 and linux/arm64 (manifest list — Docker picks the right one for you)
  • Size: ~25 MB compressed, ~30 MB extracted
  • Entrypoint: /cariosan
  • Default command: /cariosan (runs the HTTP/WS server)
  • Healthcheck: built-in via /cariosan healthcheck. Docker Compose's healthcheck: directive can call it directly.

What's NOT in the image

  • No sh, bash, curl, or apt — distroless. Use docker compose exec against a sidecar if you need an interactive shell.
  • No Postgres or Redis — those run alongside, see docker-compose.
  • No TLS termination — front the server with Caddy, nginx, or a load balancer.

Verifying the image

Every release is signed via cosign with a keyless OIDC signature backed by GitHub Actions.

terminal
cosign verify \
  --certificate-identity-regexp 'https://github.com/cariosan/cariosan/.+' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/cariosan/server:v0.1.0

A successful verification confirms the image was built by the official Cariosan GitHub repository in a GitHub-hosted runner — not pushed manually by someone holding a leaked credential.

Common operations

Run a single container (smoke test)

terminal
docker run --rm -p 8080:8080 \
  -e CARIOS_ENV=dev \
  -e CARIOS_DATABASE_URL=postgres://... \
  -e CARIOS_REDIS_URL=redis://... \
  -e CARIOS_JWT_SECRET=$(openssl rand -base64 48) \
  -e CARIOS_S3_ENDPOINT=http://... \
  -e CARIOS_S3_BUCKET=cariosan-attachments \
  -e CARIOS_S3_ACCESS_KEY=minioadmin \
  -e CARIOS_S3_SECRET_KEY=minioadmin \
  -e CARIOS_S3_PUBLIC_URL=http://localhost:9000 \
  ghcr.io/cariosan/server:v0.1.0

For a complete stack with Postgres, Redis, and MinIO wired in, use the docker-compose template.

Inspect the binary version

terminal
docker run --rm ghcr.io/cariosan/server:v0.1.0 /cariosan version

Prints the version + build SHA.

Run the bootstrap CLI

terminal
docker compose exec cariosan-server /cariosan workspace create \
  --name "My Company" --plan free

CLI is built into the same binary — no separate image.

Migrating tags in production

When upgrading from vX.Y.Z to a newer minor, read the changelog for breaking changes first. Then in your docker-compose.yml:

docker-compose.yml
services:
  cariosan-server:
    image: ghcr.io/cariosan/server:v0.2.0   # was v0.1.0

Pull + recreate:

terminal
docker compose pull cariosan-server
docker compose up -d cariosan-server

The server applies pending database migrations on boot.

Next steps

Was this page helpful?

On this page