Lemur manages TLS certificate creation. While not able to issue certificates itself, Lemur acts as a broker between CAs and environments, providing a central portal for developers to issue TLS certificates with 'sane' defaults.
Lemur aims to support three of the most recent python releases which have been released for at least a year. For example, if python 3.13 released last month, we'd aim to support versions 3.10, 3.11, and 3.12.
Build
npm install # Install dependencies
gulp build # Compiles frontend
gulp package --urlContextPath="" # Sets correct base path to API endpointsRun
gulp serve
- Supposed you have uv installed
- Activate virtual environment:
source .venv/bin/activate - Install python dependencies:
uv sync - Review initial config in
lemur.conf.pyand adjust it to your needs - Make sure you are inside lemur package (with the migrations folder):
cd lemur/ - Create admin user with login
lemurand passwordpassword:uv run lemur -c /path/to/lemur.conf.py init -p password - Run app:
uv run lemur -c /path/to/lemur.conf.py start - Access via browser: http://localhost:8000
# Install test dependencies
uv sync --group tests
# Run tests
pytest
# With coverage
pytest --cov=lemurdocker compose up -d postgres # run postgres in background
docker compose run --rm lemur init # initialize database (one time)
docker compose up -d lemur # start the app# Start services
docker-compose -f docker-compose.dev.yml up
# Start in background
docker-compose -f docker-compose.dev.yml up -d
# View logs
docker-compose -f docker-compose.dev.yml logs -f lemur
# Stop services
docker-compose -f docker-compose.dev.yml down
# Rebuild after code changes
docker-compose -f docker-compose.dev.yml up --build
# Run database migrations
docker-compose -f docker-compose.dev.yml exec lemur lemur db upgrade
# Access Python shell
docker-compose -f docker-compose.dev.yml exec lemur lemur shellThe development docker-compose includes --reload flag for gunicorn, so Python changes are automatically detected.
┌─────────────────────────────────────────────────────┐
│ Browser/Client │
└─────────────────────┬───────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────┐
│ Caddy/your favorite web server (port 80/433) │
│ • Serves static files (CSS, JS, images) │
│ • Proxies /api/* to Flask backend │
│ • SPA routing (all routes → index.html) │
└─────────────────────┬───────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────┐
│ Flask + Gunicorn (port 8000) │
│ • REST API endpoints (/api/1/*) │
│ • Serves index.html for root route │
│ • SQLAlchemy ORM │
└─────────┬───────────────────────────┬───────────────┘
│ │
↓ ↓
┌──────────────────┐ ┌──────────────────┐
│ PostgreSQL │ │ Redis │
│ (port 5432) │ │ (port 6379) │
│ • Main database │ │ • Cache/Queue │
│ • pg_trgm ext │ │ • Celery broker │
└──────────────────┘ └──────────────────┘
│
↓
┌──────────────────┐
│ Celery Worker │
│ • Background │
│ tasks │
└──────────────────┘
Happy certificate management! 🎉