Pacerino abed2d2c69 [CI] Add Dockerfile, entrypoint and GitHub Actions 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.
2026-06-14 02:35:56 +02:00
2022-09-26 15:42:26 +02:00

Caddy Proxy Manager - CPM

Shoutout

Much was copied from the original Nginx Proxy Manager and implemented for Caddy. The complete basic idea therefore goes back to the repo of jc21 and so the honor goes to him! So please have a look at his repo and his Nginx Proxy Manager too!


Idea

This project tries to implement the basic idea of the Nginx Proxy Manager for Caddy and thus provide a web interface for Caddy.

Currently the version is completely unstable and untidy.

Caddy is installed normally on the system and integrates further Caddyfiles via Caddyfile. So a hotreload and caddyfiles per host is possible.

Current features

  • Adding, editing and deleting hosts with multiple domains/upstreams
  • Two ways to apply config to Caddy, selectable at runtime:
    • Caddyfile mode (CPM_CADDY_MODE=caddyfile, default): renders a per-host Caddyfile snippet and triggers a reload.
    • API mode (CPM_CADDY_MODE=api): manages Caddy's JSON config through the admin API, maintaining one route per host (no reload needed).
  • Configurable authentication: local email/password or external OIDC/OAuth (CPM_AUTH_MODE=local|oidc) with JIT user provisioning.
  • Modern SPA frontend (Vite + React + TypeScript + Tailwind + shadcn/ui), embedded in the binary by default or served from an external directory.

Configuration

All options are environment variables prefixed with CPM_:

Variable Default Description
CPM_CADDY_MODE caddyfile caddyfile or api
CPM_CADDY_ADMINURL http://localhost:2019 Caddy admin API base URL (api mode + api reload)
CPM_CADDY_SERVERNAME srv0 http server name routes are managed under (api mode)
CPM_CADDY_LISTEN :80,:443 listen addresses for the bootstrapped server (api mode); use e.g. :8080 for local non-root testing
CPM_CADDY_RELOADSTRATEGY systemd systemd, exec, api or none (caddyfile mode)
CPM_CADDY_BINARY caddy caddy executable for the exec reload strategy
CPM_CADDY_SERVICE caddy.service systemd unit for the systemd reload strategy
CPM_DATAFOLDER /etc/caddy/ data + per-host config folder
CPM_LOGFOLDER /var/log/caddy per-host log folder
CPM_CADDYFILE /etc/caddy/Caddyfile main Caddyfile (used by exec/api reload)
CPM_FRONTENDDIR (empty) serve the frontend from this directory instead of the embedded assets
CPM_AUTH_MODE local local or oidc
CPM_AUTH_OIDC_ISSUER (empty) OIDC issuer URL (e.g. Keycloak/Authelia)
CPM_AUTH_OIDC_CLIENTID (empty) OIDC client id
CPM_AUTH_OIDC_CLIENTSECRET (empty) OIDC client secret
CPM_AUTH_OIDC_REDIRECTURL (empty) callback URL, e.g. https://cpm.example.com/api/auth/oidc/callback
CPM_AUTH_OIDC_SCOPES openid,profile,email requested scopes
CPM_AUTH_OIDC_ALLOWEDDOMAINS (empty) optional email-domain allowlist for JIT provisioning

Planned features

  • Logview
  • Manage Plugins

FAQ

Can I use the Caddy admin API instead of writing a Caddyfile?

Yes. Set CPM_CADDY_MODE=api and CPM will manage Caddy's JSON config through the admin API, keeping one route per host. The Caddyfile mode remains the default and is the simplest setup, since features like HSTS, HTTP/2, SSL etc. come for free.

Can I use external SSO (Authelia, Keycloak, etc.)?

Yes. Set CPM_AUTH_MODE=oidc and configure the CPM_AUTH_OIDC_* variables. On first successful login CPM creates the matching user automatically (JIT). Use CPM_AUTH_OIDC_ALLOWEDDOMAINS to restrict which email domains may sign in.

How can I use CPM?

You have to compile CPM yourself. The frontend (Vite + React + TypeScript) is built from the frontend directory with npm install && npm run build, which outputs straight into backend/embed/assets. The backend is written in Go (1.24+) and can be compiled with go build ./cmd/main.go from the backend directory, producing a single binary with the frontend embedded. During development run npm run dev (Vite proxies /api to the Go backend on port 3001).

Docker

A multi-stage Dockerfile builds the frontend, compiles the backend (CGO is required by the SQLite driver) and produces a small Alpine runtime image that bundles Caddy. The container entrypoint starts Caddy with its admin API and then CPM in api mode.

docker build -t caddyproxymanager .
docker run -d --name cpm \
  -p 3001:3001 -p 80:80 -p 443:443 \
  -v cpm-data:/data \
  caddyproxymanager

Published images are available at ghcr.io/pacerino/caddyproxymanager.

Development & testing

# Backend tests
cd backend && go test ./...

# Frontend type-check + build
cd frontend && npm run build

CI (GitHub Actions, .github/workflows/ci.yml) runs the backend tests with the race detector, builds the frontend, and on pushes to master / version tags builds and publishes the Docker image to GHCR.

Contribution

If you want to help with the development pull requests etc. are welcome!

Description
No description provided
Readme MIT 867 KiB
Languages
Go 69.9%
TypeScript 25.8%
Shell 2.1%
CSS 1%
Dockerfile 0.9%
Other 0.3%