Deployment & Infrastructure
Lexigram applications are ordinary ASGI apps with a clean lifecycle, so they deploy like any modern Python service. This guide covers running, packaging, and configuring for production.
For the full command reference, see the lexigram-cli package.
1. Running the Application
Section titled “1. Running the Application”A Lexigram Application is an ASGI callable (it auto-starts on first request), so you have several ways to run it.
During development
Section titled “During development”# Auto-detects create_app() and serves with reloadlexigram run
# Pick the entry point, server, and port explicitlylexigram run my_app.app:create_app --server uvicorn --port 8000lexigram run supports --host, --port, --workers, --reload/--no-reload, --profile (sets LEX_PROFILE), and --server (uvicorn, granian, or hypercorn).
In production
Section titled “In production”Point any ASGI server at your factory or app object:
uvicorn my_app.app:create_app --factory --host 0.0.0.0 --port 8000# orgranian --interface asgi my_app.app:create_app --factoryNon-web apps (workers, CLIs)
Section titled “Non-web apps (workers, CLIs)”For applications without an HTTP server, run the lifecycle directly — run_application starts the app and shuts down cleanly on SIGINT/SIGTERM:
import asynciofrom lexigram import Application, run_applicationfrom my_app.app import create_app
asyncio.run(run_application(create_app()))2. Configuration in Production
Section titled “2. Configuration in Production”Drive everything through profiles and environment variables — never commit secrets.
export LEX_PROFILE=production # loads application.production.yaml over the baseexport LEX_SQL__BACKEND__URL=postgresql+asyncpg://...export LEX_AUTH__SECRET_KEY=...Any config key can be overridden with a LEX_-prefixed env var using __ for nesting (see YAML Configuration). Set LEX_QUIET=true to suppress the startup banner in container logs.
3. Health Checks
Section titled “3. Health Checks”lexigram-monitor exposes liveness/readiness endpoints (default /health), and Application provides programmatic probes for orchestrators:
await app.liveness() # is the process alive?await app.readiness() # ready to serve traffic?await app.startup_check() # finished booting?await app.health_check() # aggregated provider healthWire these to your Kubernetes livenessProbe / readinessProbe.
4. Production Dockerfile
Section titled “4. Production Dockerfile”A multi-stage build with uv keeps images small:
FROM python:3.12-slim-bookworm AS builderCOPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/WORKDIR /appCOPY pyproject.toml uv.lock ./RUN uv sync --frozen --no-dev
FROM python:3.12-slim-bookwormWORKDIR /appCOPY --from=builder /app/.venv /app/.venvCOPY . .ENV PATH="/app/.venv/bin:$PATH"ENV LEX_PROFILE=productionEXPOSE 8000CMD ["lexigram", "run", "--no-reload", "--host", "0.0.0.0", "--port", "8000"]5. Docker Compose (Local Dev)
Section titled “5. Docker Compose (Local Dev)”services: api: build: . ports: - "8000:8000" environment: LEX_PROFILE: development LEX_SQL__BACKEND__URL: postgresql+asyncpg://app:secret_pass@db/app_db depends_on: - db
db: image: postgres:16 environment: POSTGRES_DB: app_db POSTGRES_USER: app POSTGRES_PASSWORD: secret_pass6. Pre-Deploy Checklist
Section titled “6. Pre-Deploy Checklist”LEX_PROFILE=productionand all secrets supplied via env vars.debug: false(validated byconfig.validate_for_environment(Environment.PRODUCTION)).- Database
poolsizes andweb.server.workerstuned for your instance. - Liveness/readiness probes wired to the health endpoints.
- Migrations applied:
lexigram db upgrade.
Next Steps
Section titled “Next Steps”- Configuration — profiles and env-var overrides
- Project Structure — the layouts referenced above
- The Ecosystem — observability and reliability packages