From 8850ada3be569115d096a6ec70d4152e556a31d4 Mon Sep 17 00:00:00 2001 From: gilesb Date: Wed, 7 Jan 2026 12:04:47 +0000 Subject: [PATCH] feat: Docker support for L1 server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dockerfile for L1 server/worker - docker-compose.yml with Redis - Environment variables for Redis URL and cache dir 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- Dockerfile | 18 ++++++++++++++ celery_app.py | 7 ++++-- docker-compose.yml | 58 ++++++++++++++++++++++++++++++++++++++++++++++ server.py | 13 ++++++++--- 4 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4a7d979 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application +COPY . . + +# Create cache directory +RUN mkdir -p /data/cache + +ENV PYTHONUNBUFFERED=1 + +# Default command runs the server +CMD ["python", "server.py"] diff --git a/celery_app.py b/celery_app.py index 4f7aaf6..3e5a17e 100644 --- a/celery_app.py +++ b/celery_app.py @@ -5,12 +5,15 @@ Distributed rendering for the Art DAG system. Uses the foundational artdag language from GitHub. """ +import os from celery import Celery +REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379/5') + app = Celery( 'art_celery', - broker='redis://localhost:6379/5', - backend='redis://localhost:6379/5', + broker=REDIS_URL, + backend=REDIS_URL, include=['tasks'] ) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dd19548 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,58 @@ +version: "3.8" + +services: + redis: + image: redis:7-alpine + volumes: + - redis_data:/data + networks: + - artdag + deploy: + replicas: 1 + restart_policy: + condition: on-failure + + l1-server: + build: . + image: git.rose-ash.com/art-dag/l1-server:latest + ports: + - "8100:8100" + environment: + - REDIS_URL=redis://redis:6379/5 + volumes: + - l1_cache:/data/cache + depends_on: + - redis + networks: + - artdag + deploy: + replicas: 1 + restart_policy: + condition: on-failure + + l1-worker: + build: . + image: git.rose-ash.com/art-dag/l1-server:latest + command: celery -A celery_app worker --loglevel=info + environment: + - REDIS_URL=redis://redis:6379/5 + volumes: + - l1_cache:/data/cache + - effects:/app/effects + depends_on: + - redis + networks: + - artdag + deploy: + replicas: 2 + restart_policy: + condition: on-failure + +volumes: + redis_data: + l1_cache: + effects: + +networks: + artdag: + driver: overlay diff --git a/server.py b/server.py index 8d463d7..febce99 100644 --- a/server.py +++ b/server.py @@ -21,16 +21,23 @@ from fastapi.responses import FileResponse from pydantic import BaseModel import redis +from urllib.parse import urlparse from celery_app import app as celery_app from tasks import render_effect -# Cache directory -CACHE_DIR = Path.home() / ".artdag" / "cache" +# Cache directory (use /data/cache in Docker, ~/.artdag/cache locally) +CACHE_DIR = Path(os.environ.get("CACHE_DIR", str(Path.home() / ".artdag" / "cache"))) CACHE_DIR.mkdir(parents=True, exist_ok=True) # Redis for persistent run storage -redis_client = redis.Redis(host='localhost', port=6379, db=5) +REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379/5') +parsed = urlparse(REDIS_URL) +redis_client = redis.Redis( + host=parsed.hostname or 'localhost', + port=parsed.port or 6379, + db=int(parsed.path.lstrip('/') or 0) +) RUNS_KEY_PREFIX = "artdag:run:"