Caddy Proxy Manager
Web interface for managing Caddy Server reverse proxies, redirects, and certificates.
Overview
This project provides a web UI for Caddy Server, eliminating the need to manually edit JSON configurations or Caddyfiles. It handles reverse proxies, redirects, dead hosts (maintenance pages), access lists, and certificate management through a Material UI interface.
Key features:
- Reverse proxy configuration with upstream pools and custom headers
- HTTP basic auth access lists
- Automatic HTTPS via Caddy's ACME (Let's Encrypt) with Cloudflare DNS-01 support
- Custom certificate import (internal CA, wildcards, etc.)
- Audit logging of all configuration changes
- Login rate limiting and session management
- Built with Next.js 16, React 19, Drizzle ORM, and TypeScript
Installation
Docker Compose
git clone https://github.com/fuomag9/caddy-proxy-manager.git
cd caddy-proxy-manager
cp .env.example .env
# Edit .env with your credentials (see Configuration section below)
docker compose up -d
The stack includes:
web- Next.js app with SQLite databasecaddy- Custom Caddy build (includes Cloudflare DNS and Layer4 modules)
Data is persisted in:
./data- Application database and certificates./caddy-data- ACME certificates./caddy-config- Caddy runtime config
Local Development
npm install
cp .env.example .env
# Edit .env with your credentials
npm run dev
Access the interface at http://localhost:3000/login.
Login attempts are rate-limited (5 attempts per 5 minutes, 15 minute lockout after repeated failures).
Features
| Module | Description |
|---|---|
| Proxy Hosts | HTTP/HTTPS reverse proxies with upstream pools, custom headers, Authentik forward auth |
| Redirects | 301/302 redirects with optional query string preservation |
| Dead Hosts | Maintenance pages with custom status codes |
| Access Lists | HTTP basic auth user management for proxy hosts |
| Certificates | Custom SSL/TLS certificate import (Caddy auto-manages Let's Encrypt) |
| Settings | ACME email and Cloudflare API configuration |
| Audit Log | Chronological log of all configuration changes |
Technical Stack:
- Next.js 16 App Router with React 19
- Material UI (dark theme)
- Drizzle ORM with SQLite
- Direct integration with Caddy Admin API
- Cloudflare DNS-01 challenge support for wildcard certificates
- bcrypt for access list password hashing
Configuration
Environment Variables
| Variable | Description | Default | Required |
|---|---|---|---|
SESSION_SECRET |
Session encryption key (32+ chars) | None | Yes |
ADMIN_USERNAME |
Admin login username | admin |
Yes |
ADMIN_PASSWORD |
Admin password (see requirements below) | admin (dev only) |
Yes |
BASE_URL |
Public URL of the dashboard | http://localhost:3000 |
No |
CADDY_API_URL |
Caddy Admin API endpoint | http://caddy:2019 (prod)http://localhost:2019 (dev) |
No |
DATABASE_URL |
SQLite database URL | file:/app/data/caddy-proxy-manager.db |
No |
CERTS_DIRECTORY |
Certificate storage directory | ./data/certs |
No |
LOGIN_MAX_ATTEMPTS |
Max login attempts before rate limit | 5 |
No |
LOGIN_WINDOW_MS |
Rate limit window in milliseconds | 300000 (5 min) |
No |
LOGIN_BLOCK_MS |
Rate limit block duration in milliseconds | 900000 (15 min) |
No |
Production Security Requirements (Strictly Enforced):
The application will fail to start in production if these requirements are not met:
-
SESSION_SECRET:- Must be at least 32 characters long
- Cannot be a known placeholder value
- Generate with:
openssl rand -base64 32
-
ADMIN_USERNAME:- Must be set (any value is acceptable, including
admin)
- Must be set (any value is acceptable, including
-
ADMIN_PASSWORD:- Minimum 12 characters
- Must include uppercase letters (A-Z)
- Must include lowercase letters (a-z)
- Must include numbers (0-9)
- Must include special characters (!@#$%^&* etc.)
- Cannot be
adminin production
Development Mode:
- Default credentials (
admin/admin) are allowed in development - Set
NODE_ENV=developmentto use relaxed validation
Architecture
caddy-proxy-manager/
├── app/ # Next.js App Router
│ ├── (auth)/ # Authentication pages
│ ├── (dashboard)/ # Dashboard and feature modules
│ ├── api/ # API routes
│ └── providers.tsx # Theme providers
├── src/lib/ # Core business logic
│ ├── models/ # Database models
│ ├── caddy/ # Caddy config generation
│ └── auth/ # Authentication
├── drizzle/ # Database migrations
├── docker/
│ ├── web/ # Next.js Dockerfile
│ └── caddy/ # Custom Caddy build
├── docker-compose.yml # Deployment stack
└── data/ # SQLite + certificates
Security
Authentication:
- Production mode enforces strong credentials (12+ chars, mixed case, numbers, special characters)
- Application refuses to start with weak passwords in production
- 32+ character session secrets required
- Login rate limiting: 5 attempts per 5 minutes, 15 minute lockout
- Single admin user model
Data Protection:
- Imported certificates stored with
0600permissions - Session encryption with validated secrets
- API tokens redacted after initial entry
- Audit trail for all configuration changes
- HSTS headers applied to managed hosts
Production Setup:
export SESSION_SECRET=$(openssl rand -base64 32)
export ADMIN_USERNAME="admin"
export ADMIN_PASSWORD="YourStr0ng-P@ssw0rd123!"
echo "SESSION_SECRET=$SESSION_SECRET" > .env
echo "ADMIN_USERNAME=$ADMIN_USERNAME" >> .env
echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env
chmod 600 .env
Development Mode:
export NODE_ENV=development
npm run dev
# Login with admin/admin
Limitations:
- Certificate private keys stored unencrypted in SQLite
- In-memory rate limiting (not suitable for multi-instance deployments)
- No 2FA support
Certificate Management
Automatic HTTPS (Default):
Caddy automatically obtains and renews Let's Encrypt certificates for all proxy hosts. Just add a domain and certificates are handled automatically.
For wildcard certificates, configure Cloudflare DNS-01 in Settings (see below).
Custom Certificates (Optional):
Import your own certificates for:
- Internal CA certificates
- Certificates from other providers
- Compliance requirements
To import:
- Go to Certificates page
- Click Import Custom Certificate
- Enter certificate name and domains
- Paste certificate PEM (full chain recommended)
- Paste private key PEM
- Assign to proxy hosts as needed
Note: Private keys are stored in SQLite without encryption.
Cloudflare DNS-01 Setup
For wildcard certificates or DNS-01 challenge:
- Go to Settings
- Create a Cloudflare API token with
Zone.DNS:Editpermissions - Enter token (not displayed again after saving)
- Optionally add Zone ID / Account ID
- Set ACME email for certificate notifications
To revoke: Select "Remove existing token" in Settings.
Development
| Command | Description |
|---|---|
npm run dev |
Development server with hot reload |
npm run build |
Production build |
npm start |
Run production server |
npm run typecheck |
TypeScript type checking |
npm run db:migrate |
Apply database migrations |
Notes:
- Drizzle migrations are in
/drizzle - Caddy config regenerated on each mutation and pushed via Admin API
- Rate limiting is in-memory (not suitable for multi-instance deployments)
- Single admin user architecture
Roadmap
- Multi-user RBAC
- Additional DNS providers (Route53, Namecheap, etc.)
- Backup/restore
- API for programmatic configuration
Open an issue for feature requests.
Contributing
Contributions welcome:
- Fork the repository
- Create a feature branch (
git checkout -b feature/name) - Commit changes (
git commit -m 'Add feature') - Push to branch (
git push origin feature/name) - Open a Pull Request
- Follow the existing code style (TypeScript, Prettier formatting)
- Add tests for new features when applicable
- Update documentation for user-facing changes
- Keep commits focused and write clear commit messages
Support
- Issues: GitHub Issues for bugs and feature requests
- Discussions: GitHub Discussions for questions and ideas
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Caddy Server – The amazing web server that powers this project
- Nginx Proxy Manager – The original project
- Next.js – React framework for production
- Material UI – Beautiful React components
- Drizzle ORM – Lightweight SQL migrations and type-safe queries