Add Caddy reverse proxy as an HTTPS-capable alternative to nginx#1236
Merged
Conversation
Adds a new projects/caddy/ service that mirrors the routing in
projects/nginx/runestone one-for-one, but uses Caddy so HTTPS works with
minimal hassle: automatic Let's Encrypt for a real domain, or a
locally-trusted cert for dev via CADDY_SITE_ADDRESS.
- projects/caddy/{Caddyfile,Dockerfile,README.md}: full routing + docs
- docker-compose.yml: caddy service (+ caddy_data/caddy_config volumes)
- sample.env: documented CADDY_SITE_ADDRESS knob
The /ns exclusion that nginx did with a negative lookahead (unsupported by
Go's RE2) is reproduced via handler ordering; the 25 MiB upload limit on
/ns matches nginx byte-for-byte. Verified all routes end-to-end against
live containers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a Caddy-based reverse proxy as an HTTPS-capable alternative to the existing nginx reverse proxy, with compose wiring and documentation to support local HTTPS and public ACME certs.
Changes:
- Added a new
projects/caddy/image (Dockerfile + Caddyfile) and user documentation for HTTPS setup. - Updated
docker-compose.ymlto introduce acaddyservice (and movednginxbehind a compose profile) plus persisted Caddy state via named volumes. - Removed/pruned a set of legacy web2py controllers (including a large reduction of endpoints in
ajax.py) and updated a StudyClues base-course mapping table.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sample.env | Documents new CADDY_SITE_ADDRESS env var and expected behaviors. |
| projects/caddy/README.md | Adds setup/troubleshooting docs for local/public HTTPS with Caddy. |
| projects/caddy/Dockerfile | Defines the Caddy image and copies shared static assets for direct serving. |
| projects/caddy/Caddyfile | Implements reverse-proxy routing intended to mirror the nginx routing behavior. |
| docker-compose.yml | Adds caddy service + named volumes; puts nginx behind a compose profile. |
| bases/rsptx/web2py_server/applications/runestone/controllers/toctree.rst | Removes controller docs toctree file. |
| bases/rsptx/web2py_server/applications/runestone/controllers/proxy.py | Removes legacy proxy controller. |
| bases/rsptx/web2py_server/applications/runestone/controllers/exams.py | Removes controller. |
| bases/rsptx/web2py_server/applications/runestone/controllers/designer.py | Removes controller. |
| bases/rsptx/web2py_server/applications/runestone/controllers/books.py | Removes controller. |
| bases/rsptx/web2py_server/applications/runestone/controllers/ajax.py | Removes many deprecated endpoints; retains a small set of legacy endpoints. |
| bases/rsptx/assignment_server_api/routers/student.py | Updates base-course → StudyClues book ID mappings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # For local HTTPS set CADDY_SITE_ADDRESS=https://localhost in your .env; | ||
| # for a public site set CADDY_SITE_ADDRESS=https://your.domain. | ||
| caddy: | ||
| # profiles: [ "caddy" ] |
| # This image is an alternative to projects/nginx. It performs identical routing | ||
| # but uses Caddy so HTTPS works out of the box - automatic Let's Encrypt for a | ||
| # real domain, or a locally-trusted cert for dev. See projects/caddy/Caddyfile | ||
| # for the CADDY_SITE_ADDRESS / CADDY_ACME_EMAIL knobs. |
Comment on lines
+4
to
+15
| # **Most of this file is Deprecated.** | ||
| # The endpoints that used to live here have moved to the BookServer. Only the | ||
| # endpoints still required by the legacy web2py application remain: | ||
| # | ||
| # * ``set_tz_offset()`` -- records the browser timezone offset in the session | ||
| # (still posted to by some web2py views). | ||
| # * ``getassignmentgrade()`` -- returns a student's grade/comment for a question. | ||
| # * ``broadcast_code()`` -- lets an instructor share scratch ActiveCode with the | ||
| # whole class. | ||
| # | ||
| # If you are debugging browser-to-server API behavior you almost certainly want | ||
| # the BookServer, not this file. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a new
projects/caddy/reverse-proxy service, parallel toprojects/nginx/, that replicates the routing inprojects/nginx/runestoneone-for-one but uses Caddy so HTTPS works with minimal hassle.The goal: HTTPS locally in dev, and easy HTTPS for anyone running a single composed application, without the certbot dance.
How to try it
It's wired into compose as the
caddyservice. Set the listen address in.env:CADDY_SITE_ADDRESS:80https://localhosthttps://your.domainFor
https://localhostyou'll get a browser warning until you trust Caddy's local root once — steps are inprojects/caddy/README.md.After editing
.env:docker compose up -d caddy.Notes for reviewers
/nsexclusion: nginx used a negative lookahead(?!ns/)to keep/ns/...out of the book-static file match. Go's RE2 engine has no lookahead, so this is reproduced via handler ordering (match/nsbefore the static handlers)./nsmatches nginx byte-for-byte (Caddy'sMBis decimal, so25MiBis used, not25MB).X-Forwarded-Proto: httpsis forced on ns/assignment/admin/author; the catch-all to web2py uses the real scheme — same as the nginx config.🤖 Generated with Claude Code