MVP Shipment: Self-hosted distribution, packaging, release process #56
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
MVP Shipment Readiness — Self-Hosted Cameleer
Context
Ship Cameleer as a self-hosted product to first paying customers. Target audience: technically proficient Docker users on their own infrastructure. They get the cameleer3-server (observability product) directly — NOT the SaaS vendor plane. No Logto, no multi-tenant layer. The server's
LicenseInfo.open()default already gives unlimited features with no license token, so no license infrastructure needed for MVP.The codebase is feature-complete. The gaps are entirely in distribution, packaging, naming, documentation, and release process.
Product Definition (Self-Hosted)
What the customer deploys (5 services):
ghcr.io/cameleer-io/server:1ghcr.io/cameleer-io/dashboard:1postgres:16-alpineclickhouse/clickhouse-server:24traefik:v3Plus
ghcr.io/cameleer-io/runtime:1(auto-pulled when customer deploys Camel apps).What they do NOT get: cameleer-saas, Logto, logto-bootstrap, vendor-seed, multi-tenant provisioning.
Gap Analysis
P0 — Ship Blockers
gitea.siegeln.net/cameleer/application.yml:46→cameleer-runtime-base:latest(bare name, no registry).env.examplefor self-hosted.env.exampleis outdated and SaaS-specificclickhouse-users.xml: default user, no password,::0/0adminapplication.yml:72→CAMELEER_UI_PASSWORD:adminP1 — Important for Trust
1.0-SNAPSHOT, no git tags, CI tags:latestand:$SHAonlycameleer3-server(internal "3"),cameleer3-server-ui(verbose)/metricshealth/api/v1/healthbut no HEALTHCHECK in composeP2 — Polish (post-MVP)
_FILEsuffix for secretsdocker compose pull && up -dworks but undocumentedNaming Convention
Public Image Names (GHCR)
cameleer3-serverghcr.io/cameleer-io/servercameleer3-server-uighcr.io/cameleer-io/dashboardcameleer-runtime-baseghcr.io/cameleer-io/runtimeGitHub org:
cameleer-io(GitHub doesn't allow dots in org names;cameleer.iodomain →cameleer-ioorg).Image Tagging Strategy
1.0.0ghcr.io/cameleer-io/server:1.0.01.01.env— gets patches + featureslatestDocker Compose Naming (self-hosted)
cameleername: cameleercameleer-server,cameleer-dashboard,cameleer-db,cameleer-clickhouse,cameleer-proxycontainer_name:cameleer-db-data,cameleer-ch-data,cameleer-jars,cameleer-certsname:cameleer(internal),cameleer-routing(Traefik ↔ deployed apps)name:Implementation Plan
Phase 1: Registry & Release Pipeline
Goal: Images pullable from public GHCR with semantic versioning.
Tasks:
cameleer-io, enable GHCR packageswrite:packagesscope, add asGHCR_TOKENsecret in Gitea CI.gitea/workflows/release.ymltocameleer3-serverrepo:push: tags: ['v*']server,dashboard,runtime1.0.0,1.0,1,latest)pom.xmlversion from1.0-SNAPSHOTto1.0.0v1.0.0, verify GHCR images are public and pullable without authCritical files:
cameleer3-server/.gitea/workflows/release.yml(new)cameleer3-server/pom.xml(version bump)Note on runtime-base: Currently built in cameleer-saas CI (
docker/runtime-base/Dockerfile). The release workflow needs to also build this image. Either move the Dockerfile to the server repo, or add a GHCR push step to the SaaS CI's release workflow.Phase 2: Self-Hosted Distribution Repo
Goal: Customer can clone one repo and have everything needed.
Tasks:
cameleer-io/self-hostedrepo on GitHub (public)docker-compose.ymlwith 5 services + proper health checks:proxy(Traefik v3): ports 80/443, Docker socket, TLS certsserver(ghcr.io/cameleer-io/server:1): Docker socket, JAR volume, connects to both networksdashboard(ghcr.io/cameleer-io/dashboard:1): nginx proxies/api/to serverdb(postgres:16-alpine): health check viapg_isreadyclickhouse(clickhouse/clickhouse-server:24): health check viaclickhouse-client.env.examplewith <10 required vars:config/traefik.yml— simplified (no Logto routing, no admin-console port)config/traefik-dynamic.yml— TLS default cert, root redirect to dashboardconfig/clickhouse-users.xml— with password auth from env varconfig/clickhouse-init.sql—CREATE DATABASE IF NOT EXISTS cameleer;install.sh:docker compose pull(including runtime image pre-pull)docker compose up -dKey compose design:
CAMELEER_RUNTIME_BASE_IMAGE=ghcr.io/cameleer-io/runtime:${CAMELEER_VERSION:-1}CAMELEER_DOCKER_NETWORK=cameleer-routingCAMELEER_ROUTING_DOMAIN=${CAMELEER_HOST:-localhost}CAMELEER_SERVER_URL=http://cameleer-server:8081cameleer-jarsvolume/api/tohttp://server:8081/api/Phase 3: Server Hardening for Self-Hosted
Goal: Fix P0 security gaps and runtime image config.
Tasks in cameleer3-server repo:
application.yml:46:cameleer-runtime-base:latest→ghcr.io/cameleer-io/runtime:latestmicrometer-registry-prometheustocameleer3-server-app/pom.xmlapplication.yml:104:include: health→include: health,prometheusPhase 4: Documentation
Tasks (in
cameleer-io/self-hostedrepo):README.md— Quick Start (prerequisites, one-command install, first login)docs/configuration.md— Every env var with description, default, exampledocs/architecture.md— Component diagram, data flow, network topologydocs/instrumenting-your-app.md— Add agent JAR to a Camel appdocs/upgrade.md— Standard upgrade, backup, rollbackdocs/troubleshooting.md— Top 10 issuesdocs/oidc.md— Optional OIDC setup (Keycloak, Azure AD, Okta)Phase 5: cameleer.io Domain Setup
get.cameleer.io— curl install script redirectdocs.cameleer.io— Documentation sitereleases.cameleer.io/latest— Version check endpointRelease Process
First Release (v1.0.0)
main, updatepom.xml:1.0-SNAPSHOT→1.0.0v1.0.0→ triggers release CI → GHCR + GiteaCAMELEER_VERSION=1default./install.sh→ login → deploy appVersion Numbering
Customer Experience
Upgrade:
docker compose pull && docker compose up -dUninstall:
Verification Checklist
./install.sh→ all 5 services healthy → login worksdocker compose down -v→ no orphaned resourcesadminafter installCritical Files
.gitea/workflows/release.ymlpom.xml1.0-SNAPSHOT→1.0.0application.yml:46ghcr.io/cameleer-io/runtime:latestapplication.yml:103-104prometheusto actuator endpointscameleer3-server-app/pom.xmlmicrometer-registry-prometheusdocker-compose.yml.env.exampleinstall.shconfig/*README.md+docs/*Registry Alternatives (for future reference)
If GHCR is later undesirable, evaluated alternatives:
gitea.siegeln.netcontainer packagesgitea.siegeln.netURL less professional (fixable with CNAMEregistry.cameleer.io)docker saveto .tar.gz, attach to Gitea releasesIndustry Research Summary
Patterns observed from GitLab, Sentry, Plausible, Mattermost, n8n, PostHog:
getsentry/self-hosted, Plausibleplausible/hosting, Mattermostmattermost/docker).docker compose pull && up -dwith auto-migration on startup..env.examplewith comments. Support_FILEsuffix for secrets./healthendpoint + optional/metricsfor Prometheus.1.0.0,1.0,1,latest). Tag-triggered CI.LICENSE_KEY) most common.LicenseInfo.open()pattern matches n8n/Mattermost CE approach.