Skip to content

Deployment

This guide covers how to deploy the QuoinAPI application using Docker.

Docker Deployment

The project includes a production-ready Dockerfile and docker-compose.yml for containerized deployment.


Local Docker Development

Run the entire stack (Application + PostgreSQL Database) locally using Docker Compose:

just up

This command:

  • Builds the application Docker image
  • Starts PostgreSQL container
  • Starts the application container
  • Configures networking between containers

Access the application at http://localhost:8000 (or via http://api.quoin-api.orb.local if using OrbStack).

Stop Containers

To stop and remove all containers:

just down

Production Deployment

Building the Production Image

Build the Docker image manually for production:

docker build -t quoin-api:latest .

The Dockerfile uses a multi-stage build:

# Stage 1: Builder — install dependencies only
FROM python:3.12-slim-bookworm AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock* README.md ./
RUN uv sync --no-dev --frozen

# Stage 2: Final — lean production image
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY app/ app/
COPY alembic/ alembic/
COPY alembic.ini .
ENV PATH="/app/.venv/bin:$PATH"
ENV PYTHONPATH="/app"
# Non-root user for security
RUN addgroup --system --gid 1001 fastapi && \
    adduser --system --uid 1001 --ingroup fastapi fastapi
RUN chown -R fastapi:fastapi /app
USER fastapi
CMD ["fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"]

Running in Production

With Docker Compose:

docker-compose up -d

With Docker CLI:

# Run PostgreSQL
docker run -d \
  --name postgres \
  -e QUOIN_POSTGRES_USER=postgres \
  -e QUOIN_POSTGRES_PASSWORD=postgres \
  -e QUOIN_POSTGRES_DB=app_db \
  -p 5432:5432 \
  postgres:17-alpine

# Run Application
docker run -d \
  --name quoin-api \
  --link postgres:db \
  -p 8000:8000 \
  -e QUOIN_POSTGRES_HOST=db \
  quoin-api:latest

Environment Variables

Configure the application using environment variables. See Configuration Guide for all available options.

Production Essentials:

# Application
QUOIN_ENV=production
QUOIN_OTEL_ENABLED=true

# Database
QUOIN_POSTGRES_HOST=db
QUOIN_POSTGRES_PORT=5432
QUOIN_POSTGRES_USER=postgres
QUOIN_POSTGRES_PASSWORD=<strong-password>
QUOIN_POSTGRES_DB=app_db

Security Warning: Never commit .env files with production credentials to version control!


Health Checks

The application includes dedicated endpoints for health and readiness monitoring:

Health Probe

The /health endpoint checks if the application process is running:

curl http://localhost:8000/health

Expected response:

{
  "status": "healthy"
}

Readiness Probe

The /ready endpoint checks if the application is ready to accept traffic (e.g., database is connected):

curl http://localhost:8000/ready

Expected response (HTTP 200 OK):

{
  "status": "ready"
}

If the database is unavailable, it returns an HTTP 503 error.

Use these endpoints for:

  • Docker health checks - HEALTHCHECK directive
  • Load balancer probes - Kubernetes liveness/readiness
  • Monitoring systems - Uptime tracking

See Also