add docker setup

This commit is contained in:
2025-03-22 10:12:35 +00:00
parent 74432c9f80
commit 41ab2f04df
2 changed files with 174 additions and 0 deletions

54
Dockerfile Normal file
View File

@@ -0,0 +1,54 @@
# Arbiter Dockerfile
# Multi-stage build for smaller final image
FROM python:3.12-slim as builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY pyproject.toml ./
RUN pip install --no-cache-dir build && \
pip wheel --no-cache-dir --wheel-dir /wheels -e .
# Final stage
FROM python:3.12-slim
WORKDIR /app
# Install runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
&& rm -rf /var/lib/apt/lists/* \
&& useradd --create-home --shell /bin/bash arbiter
# Copy wheels and install
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
# Copy application
COPY src/ ./src/
COPY templates/ ./templates/
COPY alembic.ini ./
# Set ownership
RUN chown -R arbiter:arbiter /app
USER arbiter
# Environment
ENV PYTHONPATH=/app/src \
PYTHONUNBUFFERED=1 \
ARBITER_TEMPLATES_DIR=/app/templates
# Default command (API server)
CMD ["uvicorn", "arbiter.main:app", "--host", "0.0.0.0", "--port", "8000"]
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"

120
docker-compose.yml Normal file
View File

@@ -0,0 +1,120 @@
# Arbiter Docker Compose configuration
# Usage:
# Development: docker compose up
# Infrastructure only: docker compose up db redis
# Production: docker compose -f docker-compose.yml -f docker-compose.prod.yml up
services:
# PostgreSQL database
db:
image: postgres:16-alpine
container_name: arbiter-db
environment:
POSTGRES_USER: arbiter
POSTGRES_PASSWORD: arbiter
POSTGRES_DB: arbiter
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U arbiter -d arbiter"]
interval: 10s
timeout: 5s
retries: 5
# Redis for job queue and caching
redis:
image: redis:7-alpine
container_name: arbiter-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# API server
api:
build:
context: .
dockerfile: Dockerfile
container_name: arbiter-api
ports:
- "8000:8000"
environment:
ARBITER_DATABASE_URL: postgresql+asyncpg://arbiter:arbiter@db:5432/arbiter
ARBITER_REDIS_URL: redis://redis:6379/0
ARBITER_TEMPLATES_DIR: /app/templates
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
start_period: 10s
retries: 3
volumes:
- ./templates:/app/templates:ro
# Background worker
worker:
build:
context: .
dockerfile: Dockerfile
container_name: arbiter-worker
command: ["python", "-m", "arq", "arbiter.worker.settings.WorkerSettings"]
environment:
ARBITER_DATABASE_URL: postgresql+asyncpg://arbiter:arbiter@db:5432/arbiter
ARBITER_REDIS_URL: redis://redis:6379/0
ARBITER_TEMPLATES_DIR: /app/templates
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- ./templates:/app/templates:ro
# Dashboard UI
dashboard:
build:
context: ./dashboard
dockerfile: Dockerfile
container_name: arbiter-dashboard
ports:
- "3000:80"
depends_on:
api:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
# Database migrations (run once)
migrate:
build:
context: .
dockerfile: Dockerfile
container_name: arbiter-migrate
command: ["python", "-m", "alembic", "upgrade", "head"]
environment:
ARBITER_DATABASE_URL: postgresql+asyncpg://arbiter:arbiter@db:5432/arbiter
depends_on:
db:
condition: service_healthy
profiles:
- migrate
volumes:
postgres_data:
redis_data: