mirror of
https://github.com/Pacerino/CaddyProxyManager.git
synced 2026-08-01 18:08:38 -04:00
[Docs] Revise README for clarity and structure; update features and quick start instructions
This commit is contained in:
245
README.md
245
README.md
@@ -1,108 +1,185 @@
|
||||
# Caddy Proxy Manager - CPM
|
||||
<div align="center">
|
||||
|
||||
## Shoutout
|
||||
Much was copied from the [original Nginx Proxy Manager](https://github.com/NginxProxyManager/nginx-proxy-manager) and implemented for Caddy. The complete basic idea therefore goes back to the repo of [jc21](https://github.com/jc21) and so the honor goes to him! So please have a look at his repo and his Nginx Proxy Manager too!
|
||||
# Caddy Proxy Manager
|
||||
|
||||
<br>
|
||||
**A modern web interface for managing [Caddy](https://caddyserver.com/) reverse proxy hosts.**
|
||||
|
||||
## Idea
|
||||
This project tries to implement the basic idea of the Nginx Proxy Manager for Caddy and thus provide a web interface for Caddy.
|
||||
Add, edit and delete proxy hosts from a clean UI — let Caddy handle TLS, HTTP/2, HSTS and automatic certificates for you.
|
||||
|
||||
Currently the version is completely unstable and untidy.
|
||||
[](https://github.com/Pacerino/CaddyProxyManager/actions/workflows/ci.yml)
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
Caddy is installed normally on the system and integrates further Caddyfiles via Caddyfile. So a hotreload and caddyfiles per host is possible.
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
> [!WARNING]
|
||||
> This project is under active development and not yet considered stable. Use at your own risk and review the configuration before exposing it publicly.
|
||||
|
||||
## 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.
|
||||
## ✨ Features
|
||||
|
||||
## Configuration
|
||||
- **Host management** — create, edit and delete hosts with multiple domains and upstream backends.
|
||||
- **Two ways to drive Caddy**, switchable at runtime:
|
||||
- 📝 **Caddyfile mode** *(default)* — renders a per-host Caddyfile snippet and reloads Caddy.
|
||||
- 🔌 **API mode** — manages Caddy's JSON config through the admin API, one route per host, no reload required.
|
||||
- **Flexible authentication** — local email/password or external **OIDC/OAuth** (Authelia, Keycloak, Authentik, …) with just-in-time user provisioning.
|
||||
- **Single binary** — a modern SPA (Vite · React · TypeScript · Tailwind · shadcn/ui) embedded directly in the Go binary, or served from an external directory.
|
||||
- **Container-ready** — multi-stage Docker image that bundles Caddy and starts everything for you.
|
||||
|
||||
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.
|
||||
## 🚀 Quick start (Docker)
|
||||
|
||||
```bash
|
||||
docker build -t caddyproxymanager .
|
||||
docker run -d --name cpm \
|
||||
-p 3001:3001 -p 80:80 -p 443:443 \
|
||||
-v cpm-data:/data \
|
||||
caddyproxymanager
|
||||
ghcr.io/pacerino/caddyproxymanager
|
||||
```
|
||||
|
||||
Published images are available at `ghcr.io/pacerino/caddyproxymanager`.
|
||||
Then open <http://localhost:3001> and sign in with the default credentials:
|
||||
|
||||
## Development & testing
|
||||
| Email | Password |
|
||||
| --- | --- |
|
||||
| `admin@example.com` | `changeme` |
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Change the defaults via `CPM_ADMIN_EMAIL` / `CPM_ADMIN_PASSWORD` on first run.
|
||||
|
||||
The container starts Caddy (with its admin API) and CPM in `api` mode. Mount your own Caddy config at `/data/caddy.json` to customise it.
|
||||
|
||||
## 🏗️ How it works
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────────────┐ ┌─────────────────┐
|
||||
│ Browser │ ───► │ CPM (Go + embedded │ ───► │ Caddy │
|
||||
│ (React SPA) │ │ React frontend) │ │ (reverse proxy) │
|
||||
└──────────────┘ └──────────┬───────────┘ └─────────────────┘
|
||||
│
|
||||
Caddyfile mode │ writes host_<id>.conf + reload
|
||||
API mode │ PUT/PATCH/DELETE via admin API
|
||||
```
|
||||
|
||||
CPM stores hosts in a local SQLite database and applies each change to Caddy using the selected provider.
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
All settings are environment variables prefixed with `CPM_`.
|
||||
|
||||
### Caddy
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `CPM_CADDY_MODE` | `caddyfile` | Provider to use: `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` | Reload strategy (Caddyfile mode): `systemd`, `exec`, `api` or `none`. |
|
||||
| `CPM_CADDY_BINARY` | `caddy` | Caddy executable for the `exec` reload strategy. |
|
||||
| `CPM_CADDY_SERVICE` | `caddy.service` | systemd unit for the `systemd` reload strategy. |
|
||||
| `CPM_CADDYFILE` | `/etc/caddy/Caddyfile` | Main Caddyfile (used by `exec`/`api` reload). |
|
||||
|
||||
### Authentication
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `CPM_AUTH_MODE` | `local` | `local` or `oidc`. |
|
||||
| `CPM_AUTH_OIDC_ISSUER` | — | OIDC issuer URL (e.g. Keycloak/Authelia). |
|
||||
| `CPM_AUTH_OIDC_CLIENTID` | — | OIDC client ID. |
|
||||
| `CPM_AUTH_OIDC_CLIENTSECRET` | — | OIDC client secret. |
|
||||
| `CPM_AUTH_OIDC_REDIRECTURL` | — | 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` | — | Optional email-domain allowlist for JIT provisioning. |
|
||||
|
||||
### General
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `CPM_DATAFOLDER` | `/etc/caddy/` | Data + per-host config folder. |
|
||||
| `CPM_LOGFOLDER` | `/var/log/caddy` | Per-host log folder. |
|
||||
| `CPM_FRONTENDDIR` | — | Serve the frontend from this directory instead of the embedded assets. |
|
||||
| `CPM_ADMIN_EMAIL` | `admin@example.com` | Seed admin email (first run, local mode). |
|
||||
| `CPM_ADMIN_PASSWORD` | `changeme` | Seed admin password (first run, local mode). |
|
||||
|
||||
## 🧑💻 Development
|
||||
|
||||
**Prerequisites:** Go 1.24+, Node 22+, and a local [Caddy](https://caddyserver.com/docs/install) for end-to-end testing.
|
||||
|
||||
Run the backend and frontend in two terminals:
|
||||
|
||||
```bash
|
||||
# Backend tests
|
||||
cd backend && go test ./...
|
||||
# Terminal 1 — backend on :3001
|
||||
cd backend
|
||||
CPM_DATAFOLDER=./data CPM_LOGFOLDER=./data CPM_CADDY_RELOADSTRATEGY=none \
|
||||
go run ./cmd/main.go
|
||||
|
||||
# Frontend type-check + build
|
||||
cd frontend && npm run build
|
||||
# Terminal 2 — frontend dev server on :5173 (proxies /api → :3001)
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
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.
|
||||
Open <http://localhost:5173> and log in with `admin@example.com` / `changeme`.
|
||||
|
||||
## Contribution
|
||||
If you want to help with the development pull requests etc. are welcome!
|
||||
### Building a single binary
|
||||
|
||||
```bash
|
||||
cd frontend && npm run build # emits into backend/embed/assets
|
||||
cd ../backend && go build ./cmd/main.go
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
cd backend && go test ./... # backend (run with -race in CI)
|
||||
cd frontend && npm run build # frontend type-check + build
|
||||
```
|
||||
|
||||
CI ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)) runs the backend tests with the race detector, builds the frontend, and publishes the Docker image to GHCR on pushes to `master` and version tags.
|
||||
|
||||
## 🐳 Building the image yourself
|
||||
|
||||
```bash
|
||||
docker build -t caddyproxymanager .
|
||||
```
|
||||
|
||||
The multi-stage build compiles the frontend and backend (CGO is required by the SQLite driver) into a small Alpine runtime that bundles Caddy.
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
<details>
|
||||
<summary><strong>Should I use Caddyfile mode or API mode?</strong></summary>
|
||||
|
||||
Use **Caddyfile mode** (the default) for the simplest setup — CPM writes snippets that Caddy imports, and you keep all of Caddy's conveniences (automatic HTTPS, HSTS, HTTP/2). Use **API mode** when you want CPM to manage Caddy's live JSON config directly through the admin API, with no reloads.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Can I use external SSO (Authelia, Keycloak, Authentik …)?</strong></summary>
|
||||
|
||||
Yes. Set `CPM_AUTH_MODE=oidc` and configure the `CPM_AUTH_OIDC_*` variables. On first successful login CPM provisions the matching user automatically (JIT). Restrict access with `CPM_AUTH_OIDC_ALLOWEDDOMAINS`.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Does CPM run Caddy for me?</strong></summary>
|
||||
|
||||
The Docker image does — its entrypoint launches Caddy with the admin API and then CPM. For bare-metal installs, run Caddy yourself and point CPM at it (`CPM_CADDYFILE` / `CPM_CADDY_ADMINURL`) with the appropriate reload strategy.
|
||||
</details>
|
||||
|
||||
## 🗺️ Roadmap
|
||||
|
||||
- [ ] Log viewer
|
||||
- [ ] Plugin management
|
||||
- [ ] Per-host advanced directives
|
||||
|
||||
## 🙌 Acknowledgements
|
||||
|
||||
Inspired by the excellent [Nginx Proxy Manager](https://github.com/NginxProxyManager/nginx-proxy-manager) by [jc21](https://github.com/jc21) — go check it out. CPM brings the same idea to Caddy.
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Pull requests and issues are welcome! Please open an issue to discuss larger changes first.
|
||||
|
||||
## 📄 License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
Reference in New Issue
Block a user