File size: 3,340 Bytes
711aa6b
bb40e1c
 
 
 
 
711aa6b
 
 
 
 
 
 
f707fd4
 
 
711aa6b
 
 
f707fd4
 
711aa6b
 
 
 
 
f707fd4
711aa6b
f707fd4
 
711aa6b
 
 
 
 
 
f707fd4
711aa6b
 
 
 
 
76a8376
f707fd4
711aa6b
 
 
 
 
 
 
 
 
 
 
 
 
f707fd4
 
 
711aa6b
 
 
 
 
 
 
 
 
f707fd4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Dockerfile for Red Button (Shutdown-Gym) OpenEnv server.
# Lives at repo root because HuggingFace Docker SDK Spaces look for
# `Dockerfile` at the repo root by default (HF Spaces Configuration
# Reference does not expose a `dockerfile_path` frontmatter key, so the
# canonical path is `./Dockerfile`). Build from repo root:
#   docker build -t red-button:latest .
#
# Patterned on upstream `envs/coding_env/server/Dockerfile` (python:3.11-slim
# + pip-installed `openenv-core` from PyPI) per PROJECT.md Sections 10 and
# 24.1. Single-container HF Space deployment, no Docker-in-Docker. Trains
# only the server-side runtime here (no trl / unsloth / wandb): those are
# host-side training deps and would balloon the image past HF Space's
# practical pull-time budget.

FROM python:3.11-slim

# Repo root inside the image. data/problems_pool.json is loaded relative to
# CWD by ShutdownGymEnvironment, so WORKDIR must match what was used at COPY
# time. Picking /app for parity with upstream coding_env.
WORKDIR /app

# System deps:
#   * curl — HEALTHCHECK probe against /health (matches upstream coding_env)
# build-essential intentionally omitted: openenv-core / fastapi / uvicorn /
# pydantic all ship manylinux wheels on PyPI for python:3.11-slim, no native
# compilation needed.
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl \
    && rm -rf /var/lib/apt/lists/*

# Install runtime deps first for better layer caching. server/requirements.txt
# pins to the slim server-only set (openenv-core + pydantic + fastapi +
# uvicorn). Keeping it separate from pyproject.toml avoids dragging trl /
# unsloth / wandb into the deployed image.
COPY server/requirements.txt /app/server/requirements.txt
RUN pip install --no-cache-dir -r /app/server/requirements.txt

# Copy application code. red_button/ and server/ are the runtime packages;
# data/problems_pool.json is the read-only fixture loaded at every reset()
# (PROJECT.md Section 7.2). openenv.yaml is shipped so `openenv validate`
# can introspect the deployed image. pyproject.toml lets future runtime
# tooling discover the project metadata.
COPY red_button /app/red_button
COPY server /app/server
COPY data/problems_pool.json /app/data/problems_pool.json
COPY openenv.yaml /app/openenv.yaml
COPY pyproject.toml /app/pyproject.toml

# Runtime env. Defaults match PROJECT.md Section 19.3 (16 concurrent
# WebSocket sessions). PYTHONUNBUFFERED for live `docker logs`. Web
# interface (Gradio) is intentionally OFF: HF Space deployment is a pure
# OpenEnv API surface, no UI overhead.
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    MAX_CONCURRENT_ENVS=16 \
    ENABLE_WEB_INTERFACE=false \
    PORT=8000

EXPOSE 8000

# /health is registered by openenv.core.env_server.http_server.create_app
# (HealthResponse + HealthStatus.HEALTHY). curl -f flips non-2xx into a
# non-zero exit so Docker marks the container unhealthy.
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -fsS http://localhost:8000/health || exit 1

# Run the FastAPI app. server.app:app is the module-level `app` object
# wired in server/app.py via create_app(...). Direct uvicorn invocation
# matches upstream coding_env and avoids an extra Python wrapper layer.
CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "8000"]