From 6866d126cbdd1d4e139d4193824aedc55427af7b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 26 Feb 2026 16:31:11 +0000 Subject: [PATCH] Add Docker Compose setup for web chat and email worker Two services sharing a single image: - web: Chainlit chat interface on port 8000 - email-worker: IMAP polling agent (main.py) ./data is mounted for persistent storage (registrations + conversations). ./openspec is mounted read-only so knowledge-base markdown files can be edited on the host without rebuilding the image. Configuration via .env (see .env.example). https://claude.ai/code/session_015tJePX9eyQENYpJUF8XvvK --- .dockerignore | 22 ++++++++++++++++++++++ Dockerfile | 20 ++++++++++++++++++++ docker-compose.yml | 26 ++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5525403 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,22 @@ +# Secrets — never bake into the image +.env + +# Version control +.git/ +.gitignore + +# Python build artefacts +__pycache__/ +*.pyc +*.pyo +.pytest_cache/ + +# Tests — not needed at runtime +tests/ + +# Persistent data — mounted as a volume at runtime +data/ + +# Tool configs — not needed in the container +.claude/ +.gemini/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7ef07ed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.13-slim + +# Install uv +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ + +WORKDIR /app + +# Install Python dependencies — cached independently of application code +COPY pyproject.toml uv.lock ./ +RUN uv sync --frozen --no-dev --no-install-project + +# Copy application source +COPY src/ ./src/ +COPY chat_app.py main.py chainlit.toml ./ +COPY public/ ./public/ + +# Make the venv's binaries (chainlit, python, etc.) available directly +ENV PATH="/app/.venv/bin:$PATH" + +# data/ and openspec/ are expected to be mounted at runtime diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..15d6385 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +services: + + # Web chat interface — Chainlit served at http://localhost:8000 + web: + build: . + command: chainlit run chat_app.py --host 0.0.0.0 --port 8000 + ports: + - "8000:8000" + env_file: .env + volumes: + # Persistent storage for conversations and completed registrations + - ./data:/app/data + # Knowledge-base markdown files — edit on the host, no rebuild needed + - ./openspec:/app/openspec:ro + restart: unless-stopped + + # Email polling agent — checks the inbox every POLL_INTERVAL seconds + email-worker: + build: . + command: python main.py + env_file: .env + volumes: + # Shares the same data directory as the web service + - ./data:/app/data + - ./openspec:/app/openspec:ro + restart: unless-stopped