agentic-traffic / Dockerfile.openenv-api
Aditya2162's picture
Upload folder using huggingface_hub
3d2dbcf verified
# OpenEnv API container
#
# Two-stage build:
# 1. builder - compiles the vendored CityFlow Python extension
# 2. runtime - installs the API dependencies and copies the repo-local data
#
# Runtime env vars:
# DATA_DIR generated CityFlow dataset root
# default: /app/data/generated
# SPLITS_DIR train/val/test split files
# default: /app/data/splits
# CHECKPOINT_PATH optional DQN checkpoint
# default: /app/artifacts/dqn_shared/best_validation.pt
# ---------------------------------------------------------------------------
# ── Stage 1: Build CityFlow ─────────────────────────────────────────────────
FROM python:3.12-slim AS builder
# Build tools needed by CityFlow's CMake build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
libboost-all-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Copy only the CityFlow source (pybind11 is bundled as an extern submodule)
COPY third_party/CityFlow ./CityFlow
# Build and install cityflow into the builder's site-packages
RUN rm -rf ./CityFlow/build
RUN pip install --no-cache-dir ./CityFlow
# Locate the compiled .so so we can copy it to the runtime stage
RUN python -c "import cityflow, os; print(os.path.dirname(cityflow.__file__))"
# ── Stage 2: Runtime ────────────────────────────────────────────────────────
FROM python:3.12-slim AS runtime
WORKDIR /app
# Copy the compiled cityflow extension from the builder
COPY --from=builder /usr/local/lib/python3.12/site-packages/cityflow* \
/usr/local/lib/python3.12/site-packages/
# Install Python dependencies (no build tools needed here)
COPY openenv_app/requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Copy application source (only what the OpenEnv API needs at runtime)
COPY agents/ ./agents/
COPY district_llm/ ./district_llm/
COPY env/ ./env/
COPY openenv_app/ ./openenv_app/
COPY server/__init__.py ./server/__init__.py
COPY server/path_validators.py ./server/path_validators.py
COPY server/policy_runner.py ./server/policy_runner.py
COPY server/roadnet_matcher.py ./server/roadnet_matcher.py
COPY training/ ./training/
COPY data/splits/ ./data/splits/
COPY data/generated/city_0002/ ./data/generated/city_0002/
COPY artifacts/dqn_shared/best_validation.pt ./artifacts/dqn_shared/best_validation.pt
COPY artifacts/district_llm_adapter_v3/main_run/adapter/ ./artifacts/district_llm_adapter_v3/main_run/adapter/
# Keep runtime paths present, but expect the actual generated dataset to be
# mounted or synced separately instead of baked into the image.
RUN mkdir -p /app/data/generated /app/data/splits
# Default paths (overridable at runtime via env vars).
# DATA_DIR must point at a mounted/generated dataset root that contains city_*/
# directories and scenario files; only data/splits is bundled here.
ENV DATA_DIR=/app/data/generated
ENV SPLITS_DIR=/app/data/splits
ENV CHECKPOINT_PATH=/app/artifacts/dqn_shared/best_validation.pt
ENV DISTRICT_LLM_ADAPTER_PATH=/app/artifacts/district_llm_adapter_v3/main_run/adapter
# OpenEnv and HF Spaces commonly use port 7860.
EXPOSE 7860
CMD ["sh", "-c", "uvicorn openenv_app.app:app --host 0.0.0.0 --port ${PORT:-7860}"]