Skip to content

Installing Sulu (on-premise)

Audience: operators installing a licensed Sulu on-premise instance. If you're evaluating Sulu, see Getting Started → Sign up first.

What you need before starting

  • A Linux host with Docker 26+ and docker compose v2 (Ubuntu 24.04 recommended) OR a Kubernetes 1.27+ cluster (see Kubernetes deployment guide).
  • A ghcr.io pull token issued by Sulu (your account team provides this).
  • A configured SMTP relay (Resend, SES, your corporate Postfix — any standard SMTP works).
  • An S3-compatible object store for attachments (MinIO is bundled and works out of the box).
  • Public TLS termination (Caddy, nginx, or your existing reverse proxy).

Step 1: Authenticate to the image registry

Your Sulu account team issues a personal pull token. Save it once:

bash
echo "$SULU_PULL_TOKEN" | docker login ghcr.io -u <your-customer-handle> --password-stdin

The token has read-only access to the sulu-* image repositories under the ellyzz GitHub organization. It does NOT grant access to source code.

Step 2: Pull the release images

All Sulu images are hosted under the ellyzz GHCR organization.

bash
export SULU_VERSION=v0.1.0
docker pull ghcr.io/ellyzz/sulu-backend:$SULU_VERSION
docker pull ghcr.io/ellyzz/sulu-frontend:$SULU_VERSION
docker pull ghcr.io/ellyzz/sulu-landing:$SULU_VERSION
docker pull ghcr.io/ellyzz/sulu-docs:$SULU_VERSION
docker pull ghcr.io/ellyzz/sulu-backup:$SULU_VERSION

We sign every release image with cosign using GitHub's OIDC identity — there are no long-lived signing keys.

bash
cosign verify ghcr.io/ellyzz/sulu-backend:$SULU_VERSION \
  --certificate-identity-regexp='https://github.com/ellyZz/sulu/.+' \
  --certificate-oidc-issuer='https://token.actions.githubusercontent.com'

Expected: a JSON block ending in "Issuer": "https://token.actions.githubusercontent.com".

Step 4: Download the SBOM

Each release ships a CycloneDX SBOM as a release artifact:

https://github.com/ellyZz/sulu/releases/download/$SULU_VERSION/sulu-backend-$SULU_VERSION.cdx.json

Pass this through your usual SCA tooling.

Step 5: Compose or Helm

  • Docker Compose: clone the repo, use docker-compose.yml + docker-compose.prod.yml. Set SULU_VERSION in .env to pin the immutable release tag. Optional overlays: docker-compose.observability.yml for bundled Prometheus/Grafana/Loki, docker-compose.backup.yml for the sulu-backup container.

  • Kubernetes (Helm): the chart is published to oci://ghcr.io/ellyzz/charts/sulu. See Deploying on Kubernetes for the full procedure.

Step 6: Bootstrap admin

Set the following before first start:

bash
export SULU_BOOTSTRAP_ADMIN_EMAIL=[email protected]
export SULU_BOOTSTRAP_ADMIN_PASSWORD='<strong-temporary-password>'

Sulu creates this user on first boot and refuses to start if either variable is missing. Subsequent boots leave the admin row alone, so you can rotate the password via the Profile UI without redeploy.

Step 7: Health check

bash
curl -fsS http://localhost:8080/actuator/health | jq .status

Expected: "UP".

Next steps

Sulu Test Management System