The Alpine caddy package lags and lacked `list-modules --json`. Install the
official static Caddy binary pinned via ARG CADDY_VERSION (multi-arch via
TARGETARCH) instead. The entrypoint now launches ${CPM_CADDY_BINARY:-caddy}
so a mounted plugin-enabled build is used by both Caddy and CPM's detection.
Older Caddy versions don't support `list-modules --json`, which made the
plugins page fail with an opaque "exit status 1". Surface stderr in the error
and fall back to parsing the plain-text output (--packages / --skip-standard)
when --json is unsupported, so module detection works on any Caddy version.
Deploy the PR image to the self-hosted runner in API mode and run a full
end-to-end test (login, host creation, live reverse-proxy to whoami, basic
auth plugin, module discovery). The environment is published on a fixed port
3001 and left running until the PR is closed or a /teardown comment is posted.
- docker-compose.e2e.yml: cpm (API mode) + whoami upstream, per-PR isolation
- test/e2e/run.sh: full api-mode E2E assertions against the live container
- .github/workflows/pr-e2e.yml: deploy/E2E, teardown on close, /teardown comment
Add unit/integration tests across backend handlers, auth, caddy and
util packages, plus frontend component and API tests with the new
test setup. Update CI workflow and Vite config to run the suites.
Introduce per-host plugin support: Caddy module discovery, module
config endpoints, plugin schemas (basicauth, cloudflare) and the
host plugins API. On the frontend, add the Plugins page, plugin/host
plugin dialogs and schema-driven form fields.
On version tags, build static pure-Go binaries for linux, macOS and
Windows (amd64 + arm64), package them with checksums and publish a
GitHub release with the artifacts. Grant contents: write for releases.
Replace gorm.io/driver/sqlite (mattn/go-sqlite3, CGO) with
github.com/glebarez/sqlite (modernc, pure Go). Builds and tests no
longer need a C toolchain, fixing CI on runners without gcc. Drop the
race detector from CI (it requires CGO) and build a static binary in
Docker.
Revive the project: modern Go toolchain, Caddy provider abstraction
(Caddyfile + admin API modes), configurable local/OIDC auth, a rewritten
Vite/React/shadcn frontend, Docker image and CI pipeline.
Multi-stage Dockerfile builds the frontend and backend into a single
Alpine image bundling Caddy, started via an entrypoint. CI runs backend
tests (with race detector), builds the frontend and publishes the image
to GHCR on master/tags. Targets a self-hosted runner with a local build
cache. Updates .gitignore (secrets/runtime state) and README.
Replace the Create React App frontend with a modern Vite stack. Adds a
login page (local form or SSO depending on auth mode), an OIDC callback
page, and a hosts page with create/edit/delete. Build output is emitted
into backend/embed/assets for embedding in the binary.
Route host changes through the selected Caddy provider, add auth routes
and the frontend-dir serving toggle, seed a default admin user on first
run, and validate space/comma separated domain lists via a custom
validator. Includes validator tests.
Support CPM_AUTH_MODE=local|oidc. OIDC uses go-oidc with JIT user
provisioning and an optional email-domain allowlist. Adds auth config,
login and callback endpoints, a JWT signing-key bootstrap and
Provider/Subject fields on the user model. Includes OIDC allowlist tests.
Introduce a Provider interface selectable via CPM_CADDY_MODE:
- CaddyfileProvider renders per-host snippets (template whitespace fixed)
- APIProvider manages Caddy's JSON config via the admin API
Add configurable reload strategy (systemd/exec/api/none) and a
configurable listen address for the bootstrapped server in API mode.
Includes unit tests for the JSON builder, provider factory and the
API provider (httptest).