CaddyManager 0.0.1 - a web ui to manage multiple Caddy instances

Hey all, I made a post a while back asking for Caddy Configs on reddit (r/selfhosted) as I’ve been putting time into developing a UI for Caddy. The reception was overwhelming and beyond motivating to continue working on it and whilst I wasn’t able to get as much progress in as I initially wanted, I did decide to publish what is currently there with more features planned over the upcoming months!

CaddyManager is a web UI for managing multiple Caddy Servers - Currently in an “Alpha” state, being that all features that are currently in there work, but will become better in the near future!

screenshots

Standout features

  • Connect to multiple Caddy Servers and pull their configs, update them, redeploy them

  • Basic templates and form based configuration, create a new reverse proxy, api gateway, load balancer and more through a form instead of lines of json/yaml/caddyfile code

  • API keys, securely interact with the backend of CaddyManager through RESTful apis, securely utilising API Keys - there’s also docs available.

  • Multi-user, the system is multi-user, with two distinct roles (right now), admin and user.

  • Audit logging, as this is something that I’ve already started using in an enterprise setting, audit logging was a must-have. Track actions throughout the system with ease!

How to deploy

Are you an adventurous user that wouldn’t mind trying some new things? Then backup your caddy setup, open up port :2019 (or something else) in your server and head over to the example compose stack in the GitHub repo or the website

3 docker containers, yeap, that’s currently what it needs! We’ll be running MongoDB as database, a backend service, and a frontend service. If you already have a MongoDB running, feel free to tie it into that.

For an example Docker Compose, go to the website or GitHub repo - default user and password are: “admin” and “caddyrocks”

Information

Github repository here: https://github.com/caddymanager/caddymanager
Quick website here: Caddy Manager - Open Source Web UI for managing Caddy!
Dockerhub here: https://hub.docker.com/u/caddymanager

What’s next?

Plenty of features I wanna work in, but I think the key focus next few weeks will be on accessibility and UI, mainly a proper dark mode as well as screen-reader capabilities, as well as fixing bugs that people might find.

After that I’ll start working on some more exciting features like a proper dashboard, bulk actions, configuration versioning, git/s3 import/export, OIDC and more intelligent templating.

For the current roadmap: Caddy Manager - Open Source Web UI for managing Caddy!

Known issues

I’m still making a proper list but for now:

  1. when deploying you have to manually set the backend IP and expose it to the user instead of the frontend proxying it itself to the backend.
  2. No dark mode is a problem
  3. Forms and input fields are in need of some css lovin’
  4. Sometimes you have to “refresh” datasources after logging in as the last error is still preventing them from showing.
  5. Code cleanups, quite a bit of leftovers from “in-between” work/bugfixes still in the codebase, some touchups are needed here.

Time investment

As with any open source project, this stuff can be a bit scary, however, we’re starting to use this tooling at my work as well, which gives me some more resources to work with! The project itself will get continued development until the full feature list from the roadmap is built in - after that it’ll either go into maintenance mode or will receive continued development based on community engagement!

The project is MIT licensed, so feel free to fork, but would love to hear people’s ideas and thoughts, feel free to fill up the Github issues!

ps. This is my first time open sourcing anything - feel free to drop any feedback you might have, or things I should have done and missed, googling for “what to do when open sourcing your project” only takes you so far..

6 Likes

Love it! I had a few users who asked me about UI for Caddy. I’ll point them at your project :ok_hand: Impressive feat :slight_smile:

I haven’t had a chance to run the app and play with it. I’m yet to read the code thoroughly to understand how you do some parts, but I see you’re using basic auth with the admin API endpoint of Caddy yet this is not something Caddy supports. This syntax is not supported in Caddy. How are you able to do this?

3 Likes

Thanks for the compliment and having a look at the code!
It seems you’ve found a bit of late night craze of hunting through various ways of making this as secure as possible, I assumed that basic auth was possible but apparently I haven’t tested it properly because it doesn’t.. I’ll make a note to remove this and perhaps dive a bit deeper on enforce_origin as a security option to encourage users to use. Either way this is still part of the “generate server” functionality that I originally started working on but is not currently used anywhere in the application (some cleanups are due) other than a lingering api endpoint.

Check the Identity and Remote Administration parts of the article.

Basically, the admin endpoint natively supports mTLS. You can use that. Have a common CA for the servers to trust, and get a client cert from that CA to use in CaddyManager.

4 Likes

This is huge, thanks! I’ve been breaking my head about how to encourage security of the admin endpoint to users, I’ll be sure to utilise this in the next release. In the meantime I’ve removed the basic auth options - feeling a bit silly now :sweat_smile:

3 Likes

v0.0.2 - SQLite is here!

This release has a set of quality of life updates that will hopefully greatly improve everyone’s experience with CaddyManager, thank you all for playing around with it thus far!

New features

  • Multi-database engine support, with SQLite as default and MongoDB as alternative option. #22

  • Alternative JSON editor for bigger changes and copy/pasting. #32

  • Initial dashboard setup, will be improved upon in the future, as well as Open Telemetry integration.

Improvements

  • Improved all input fields readability #34 #18

  • Frontend container is now properly communicating directly with the backend, clients dont need to interact directly with backend anymore #27

  • When using domains that already exist in a config, combined with a template, the merging with the existing configuration doesn’t break the Caddy config anymore

  • Improved logging and added various cleanups throughout the codebase to improve speed

3 Likes

This is so cool. Thanks for contributing this! I’ll share this again on my X feed. I know a lot of people have wanted something like this.

1 Like

Thank you so much Matt, looking forward to putting more time into the features requested by the community!

1 Like

Hi @stolkie and CaddyManager team,

I’m experiencing critical startup failures with CaddyManager v0.0.2 that prevent the backend from running properly. Despite following the installation instructions, the backend container consistently crashes with multiple errors.

Environment Details:

  • Docker version: 27.4.1

  • Host OS: Ubuntu 24.04.1 LTS

  • CaddyManager version: 0.0.2 (Build: 27, Branch: main, Commit: 52f69b64)

  • Database engine: SQLite (default)

  • Caddy server: v2.x running on separate host (192.168.1.240:2019)

Installation Method:
Backend container

docker run -d --name caddymanager-backend
-p 3000:3000
-e DB_ENGINE=sqlite
-e CADDY_SANDBOX_URL=http://192.168.1.240:2019
-e DEFAULT_CADDY_ADMIN_USER=admin
-e DEFAULT_CADDY_ADMIN_PASSWORD=caddyrocks
-v /opt/caddymanager-data:/app/data
caddymanager/caddymanager-backend:latest

Frontend container

docker run -d --name caddymanager-frontend
-p 8002:80
-e BACKEND_HOST=localhost:3000
caddymanager/caddymanager-frontend:latest

Issues Encountered:

1. SQLite Database Connection Failure

Failed to connect to SQLite: unable to open database file
  • Occurs consistently on backend startup

  • Tried both Docker volumes and host directory mounting

  • Directory permissions set to 755

  • Container has write access to /app/data

2. YAML Parsing Error
Error in ./controllers/metricsController.js :
YAMLSemanticError: Nested mappings are not allowed in compact mappings at line 11, column 22:
description: Limit the number of historical entries returned (default: …
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^…
Not all input has been taken into account at your final specification.

  • Appears to be a code-level issue in metricsController.js

  • Suggests malformed YAML in the source code

  • May be related to OpenAPI/Swagger documentation

3. Backend Container Behavior

  • Frontend container starts and runs successfully

  • Backend container starts but crashes immediately after the errors

  • Backend never reaches running state

  • No successful API responses from backend

Complete Backend Logs:
:white_check_mark: Build information generated successfully
:package: Version: 0.0.2
:1234: Build: 27
:herb: Branch: main
:memo: Commit: 52f69b64

caddy-manager-backend@0.0.2 start
node app.js
Not all input has been taken into account at your final specification.
Here’s the report:
Error in ./controllers/metricsController.js :
YAMLSemanticError: Nested mappings are not allowed in compact mappings at line 11, column 22:
description: Limit the number of historical entries returned (default: …
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^…
Failed to connect to SQLite: unable to open database file

Network Connectivity:

  • Caddy admin API is accessible from backend container host

  • Frontend loads correctly but cannot communicate with backend

  • No firewall restrictions between containers

Attempted Solutions:

  1. Used host directory instead of Docker volumes for database storage

  2. Set explicit directory permissions (755, 777 tested)

  3. Tried different CORS_ORIGIN configurations

  4. Verified Caddy admin API accessibility

  5. Used both named volumes and bind mounts

Questions:

  1. Is there a known issue with SQLite database initialization in v0.0.2?

  2. Should the metricsController.js YAML parsing error be addressed in a future patch?

  3. Are there additional environment variables required for SQLite setup?

  4. Is there a recommended Docker Compose configuration that addresses these issues?

Request: Would it be possible to get either:

  • A fix for the SQLite connection issue

  • A working Docker Compose example for v0.0.2

  • Information about reverting to a more stable version

The concept and UI design look excellent - just need to get past these startup issues. Any guidance would be greatly appreciated.

Thanks for the great work on this project!

2 Likes

Hi @monukoshy, thank you for the extensive troubleshooting already, sorry to hear it isn’t smooth sailing yet..

first thing that comes to mind when looking at this (other than permission issues) is the batch of missing environment variables, there’s a docker compose example available here: Caddy Manager - Open Source Web UI for managing Caddy!

I realize now that I haven’t made the environment setup defensive in certain parts of the app so that means that you have to explicitly set them, otherwise it just won’t start… you can leave the MongoDB part of the compose file of course!

The yaml error is indeed a minor syntax issue I intend to resolve in an upcoming patch next couple of weeks!

I think running the above docker compose will fix the issues (namely that the SQLite path is undefined)

1 Like