Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefixed reverse proxy #171

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions reverse_proxy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
http://127.0.0.1:8080 {
handle_path /proxy/* {
reverse_proxy 127.0.0.1:9000
}
}
9 changes: 9 additions & 0 deletions reverse_proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Reverse proxy

Run chainlit on a prefix (root-path) behind [Caddy](https://caddyserver.com/) as a reverse proxy.

## Quick start
1. Install Python requirements with your favourite package manager (like uv or poetry) into your favourite (virtual) environment.
2. [Install Caddy](https://caddyserver.com/docs/install).
3. Run uvicorn and Caddy with: `./start.sh`
4. Find Chainlit at `http://127.0.0.1:8080/proxy/chainlit`.
12 changes: 12 additions & 0 deletions reverse_proxy/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from fastapi import FastAPI, Request
from chainlit.utils import mount_chainlit

app = FastAPI()


@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}


mount_chainlit(app=app, target="clapp.py", path="/chainlit")
11 changes: 11 additions & 0 deletions reverse_proxy/clapp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import chainlit as cl


@cl.on_message
async def main(message: cl.Message):
# Your custom logic goes here...

# Send a response back to the user
await cl.Message(
content=f"Received: {message.content}",
).send()
9 changes: 9 additions & 0 deletions reverse_proxy/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
name = "reverse-proxy"
version = "0.1.0"
description = "Run chainlit on a prefix (root-path) behind Caddy as a reverse proxy."
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"chainlit",
]
1 change: 1 addition & 0 deletions reverse_proxy/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chainlit
41 changes: 41 additions & 0 deletions reverse_proxy/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# Store PIDs for cleanup
declare -a pids

# Cleanup function to kill all background processes
cleanup() {
echo -e "\nReceived SIGINT (Ctrl+C). Shutting down..."

# Kill all stored PIDs
for pid in "${pids[@]}"; do
if kill -0 $pid 2>/dev/null; then
echo "Stopping process $pid"
kill $pid
wait $pid 2>/dev/null
fi
done

exit 0
}

# Set up trap for Ctrl+C
trap cleanup SIGINT

# Start first application (replace with your actual command)
echo "Starting uvicorn..."
uvicorn app:app --host 0.0.0.0 --port 9000 --root-path=/proxy &
pids+=($!)

# Start second application (replace with your actual command)
echo "Starting Caddy..."
caddy run &
pids+=($!)

echo "Both applications started. Press Ctrl+C to exit."
echo "Running processes: ${pids[*]}"

echo "Proxy server running on http://localhost:8080/proxy/chainlit"

# Wait for all background processes
wait