docs: add README with production and development setup instructions
This commit is contained in:
parent
020e6c6fa0
commit
ec1c42b1d5
1 changed files with 129 additions and 0 deletions
129
README.md
Normal file
129
README.md
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
# Porchlight
|
||||||
|
|
||||||
|
OpenID Connect Provider with user management, built with FastAPI.
|
||||||
|
|
||||||
|
Porchlight handles user registration (via magic links), credential management
|
||||||
|
(passwords and WebAuthn security keys), and issues OIDC tokens for relying
|
||||||
|
parties. It uses SQLite for storage, Jinja2 + HTMX for the UI, and idpyoidc
|
||||||
|
for the OIDC protocol layer.
|
||||||
|
|
||||||
|
## Production Setup
|
||||||
|
|
||||||
|
### Docker (recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
This starts Porchlight on port 8000 with 4 uvicorn workers. Data is persisted
|
||||||
|
in a named Docker volume.
|
||||||
|
|
||||||
|
Set required environment variables in `docker-compose.yml` or via `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
OIDC_OP_ISSUER=https://auth.example.com
|
||||||
|
OIDC_OP_SESSION_SECRET=<random-secret>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual
|
||||||
|
|
||||||
|
Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv sync --no-dev
|
||||||
|
|
||||||
|
OIDC_OP_ISSUER=https://auth.example.com \
|
||||||
|
OIDC_OP_SESSION_SECRET=$(python -c "import secrets; print(secrets.token_hex(32))") \
|
||||||
|
uv run uvicorn fastapi_oidc_op.app:create_app \
|
||||||
|
--factory --host 0.0.0.0 --port 8000 --workers 4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
All settings are read from environment variables with the `OIDC_OP_` prefix:
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `OIDC_OP_ISSUER` | **required** | OIDC issuer URL (must match public URL) |
|
||||||
|
| `OIDC_OP_SESSION_SECRET` | random per process | Session cookie signing secret |
|
||||||
|
| `OIDC_OP_DEBUG` | `false` | Enable `/docs` Swagger UI |
|
||||||
|
| `OIDC_OP_SQLITE_PATH` | `data/oidc_op.db` | SQLite database path |
|
||||||
|
| `OIDC_OP_SIGNING_KEY_PATH` | `data/keys` | OIDC signing key storage |
|
||||||
|
| `OIDC_OP_INVITE_TTL` | `86400` | Magic link expiry in seconds |
|
||||||
|
| `OIDC_OP_MANAGE_CLIENT_ID` | `manage-app` | Client ID for the management UI |
|
||||||
|
|
||||||
|
Database migrations run automatically on startup.
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Python 3.13+
|
||||||
|
- [uv](https://docs.astral.sh/uv/)
|
||||||
|
- Node.js (for e2e tests)
|
||||||
|
|
||||||
|
### Getting started
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies (including dev tools)
|
||||||
|
uv sync
|
||||||
|
|
||||||
|
# Start the dev server with hot reload
|
||||||
|
OIDC_OP_ISSUER=http://localhost:8000 OIDC_OP_DEBUG=true \
|
||||||
|
uv run uvicorn fastapi_oidc_op.app:create_app \
|
||||||
|
--factory --host 127.0.0.1 --port 8000 --reload --reload-dir src
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile dev up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Unit/integration tests
|
||||||
|
uv run pytest
|
||||||
|
|
||||||
|
# Lint and format
|
||||||
|
uv run ruff check src/ tests/ --fix
|
||||||
|
uv run ruff format src/ tests/
|
||||||
|
|
||||||
|
# Type checking
|
||||||
|
uv run ty check src/
|
||||||
|
```
|
||||||
|
|
||||||
|
### End-to-end browser tests
|
||||||
|
|
||||||
|
The e2e suite uses Playwright (Node.js) to test all user-facing flows against a
|
||||||
|
running instance of the app.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# One-time setup: install Playwright and Chromium
|
||||||
|
cd tests/e2e
|
||||||
|
npm install && npm run setup
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Run all e2e tests
|
||||||
|
./tests/e2e/run.sh
|
||||||
|
|
||||||
|
# Run a specific test
|
||||||
|
./tests/e2e/run.sh tests/e2e/test_login.js
|
||||||
|
|
||||||
|
# Run with visible browser (not headless)
|
||||||
|
E2E_HEADLESS=0 ./tests/e2e/run.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The runner starts the app on port 8099, seeds test fixtures into a temporary
|
||||||
|
SQLite database, runs all `test_*.js` files, and tears everything down.
|
||||||
|
|
||||||
|
### Full quality check
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run ruff format src/ tests/
|
||||||
|
uv run ruff check src/ tests/ --fix
|
||||||
|
uv run ty check src/
|
||||||
|
uv run pytest
|
||||||
|
./tests/e2e/run.sh
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue