Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy-hf-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ jobs:
# Cleanup
cd ..
rm -rf hf-space
rm -rf hf-staging_$ENV_NAME_$ENV_NAME
rm -rf hf-staging_$ENV_NAME

# Job to deploy single environment
deploy-single:
Expand Down
106 changes: 106 additions & 0 deletions .github/workflows/openspiel_base_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Build OpenSpiel Base Image

on:
workflow_dispatch: # Manual trigger only
inputs:
force_rebuild:
description: 'Force rebuild even if base image exists'
required: false
default: 'false'
type: boolean

env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ${{ github.repository_owner }}/openenv

jobs:
# Job 1: Build base image first
build-base:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata for base image
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-base
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha

- name: Build and push base image
uses: docker/build-push-action@v5
with:
context: .
file: src/core/containers/images/Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=base
cache-to: type=gha,mode=max,scope=base

# Job 2: Build OpenSpiel base image (depends on base)
build-openspiel-base:
runs-on: 8-core-ubuntu
needs: build-base # Wait for base image to be built
permissions:
contents: read
packages: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata for OpenSpiel base image
id: meta-openspiel-base
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-openspiel-base
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha

- name: Build and push OpenSpiel base image
uses: docker/build-push-action@v5
with:
context: .
file: src/envs/openspiel_env/server/Dockerfile.openspiel-base
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta-openspiel-base.outputs.tags }}
labels: ${{ steps.meta-openspiel-base.outputs.labels }}
cache-from: type=gha,scope=openspiel-base
cache-to: type=gha,mode=max,scope=openspiel-base

- name: Build summary
run: |
echo "✅ OpenSpiel base image built and pushed successfully!"
echo "📦 Image: ${{ steps.meta-openspiel-base.outputs.tags }}"
echo "🚀 Next regular build will use this new base image"
112 changes: 53 additions & 59 deletions scripts/prepare_hf_deployment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,63 +94,20 @@ DOCKERFILE_EOF
"openspiel_env")
# OpenSpiel requires special C++ build process - replace entire Dockerfile
cat > $CURRENT_STAGING_DIR/Dockerfile << DOCKERFILE_EOF
# OpenSpiel requires complex C++ build - using special multi-stage approach
# Stage 1: Build OpenSpiel C++ bindings
FROM python:3.11 AS openspiel-builder

# Avoid interactive prompts during build
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
clang \
cmake \
curl \
git \
sudo \
&& rm -rf /var/lib/apt/lists/*

# Set up OpenSpiel build directory
RUN mkdir /repo
WORKDIR /repo

# Clone OpenSpiel
RUN git clone https://github.com/google-deepmind/open_spiel.git .

# Run OpenSpiel's installation script (downloads C++ dependencies)
RUN ./install.sh

# Install Python dependencies
RUN pip3 install --no-cache-dir --upgrade setuptools testresources importlib_metadata
RUN pip3 install --no-cache-dir --upgrade -r requirements.txt cmake

# Build OpenSpiel with Python 3.11
RUN mkdir -p build
WORKDIR /repo/build
RUN cmake -DPython3_EXECUTABLE=$(which python3) -DCMAKE_CXX_COMPILER=$(which clang++) ../open_spiel
RUN make -j$(nproc) pyspiel

# Stage 2: Use the specified openenv-base image
FROM $BASE_IMAGE_REF

# Copy OpenSpiel build artifacts from builder
RUN mkdir -p /repo
COPY --from=openspiel-builder /repo /repo

# Install OpenSpiel Python requirements in runtime
WORKDIR /repo
RUN pip3 install --no-cache-dir --upgrade -r requirements.txt
# OpenSpiel environment using pre-built OpenSpiel base image
ARG OPENSPIEL_BASE_IMAGE=ghcr.io/meta-pytorch/openenv-openspiel-base:sha-e622c7e
FROM \${OPENSPIEL_BASE_IMAGE}

# Set Python path for OpenSpiel
ENV PYTHONPATH=/repo:/repo/build/python:${PYTHONPATH}

# Copy OpenEnv core
# Copy OpenEnv core (base image already set WORKDIR=/app)
WORKDIR /app
COPY src/core/ /app/src/core/

# Copy OpenSpiel environment
COPY src/envs/openspiel_env/ /app/src/envs/openspiel_env/

# Copy README for web interface documentation
COPY src/envs/openspiel_env/README.md /app/README.md

# Extend Python path for OpenEnv (base image set PYTHONPATH=/app/src)
# We prepend OpenSpiel paths
ENV PYTHONPATH=/repo:/repo/build/python:/app/src
Expand All @@ -160,11 +117,13 @@ ENV OPENSPIEL_GAME=catch
ENV OPENSPIEL_AGENT_PLAYER=0
ENV OPENSPIEL_OPPONENT_POLICY=random

# Health check
# Health check (curl is provided by openenv-base)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

# Run the FastAPI server
# Note: EXPOSE 8000 already set by openenv-base

# Run the FastAPI server (uvicorn installed by openenv-base)
CMD ["uvicorn", "envs.openspiel_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"]
DOCKERFILE_EOF
echo "Created special OpenSpiel Dockerfile with C++ build process"
Expand Down Expand Up @@ -205,12 +164,46 @@ create_readme() {
# Capitalize first letter of environment name
env_title=$(echo "$env_name" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')

# Set environment-specific colors and emoji
case $env_name in
"atari_env")
EMOJI="🕹️"
COLOR_FROM="#FF6200"
COLOR_TO="#D4151B"
;;
"coding_env")
EMOJI="💻"
COLOR_FROM="#007ACC"
COLOR_TO="#1E1E1E"
;;
"openspiel_env")
EMOJI="🎮"
COLOR_FROM="#9146FF"
COLOR_TO="#00FFA3"
;;
"echo_env")
EMOJI="🔊"
COLOR_FROM="#00C9FF"
COLOR_TO="#1B2845"
;;
"chat_env")
EMOJI="💬"
COLOR_FROM="#0084FF"
COLOR_TO="#25D366"
;;
*)
EMOJI="🐳"
COLOR_FROM="blue"
COLOR_TO="green"
;;
esac

cat > $CURRENT_STAGING_DIR/README.md << README_EOF
---
title: ${env_title} Environment Server
emoji: 🐳
colorFrom: blue
colorTo: green
emoji: ${EMOJI}
colorFrom: ${COLOR_FROM}
colorTo: ${COLOR_TO}
sdk: docker
pinned: false
app_port: 8000
Expand Down Expand Up @@ -310,9 +303,10 @@ Provides access to OpenSpiel games for multi-agent reinforcement learning.
Send a POST request to `/step` with:
```json
{
"action": 0
"action": {
"action_id": 1
}
}
```
README_EOF
;;
esac
Expand Down
65 changes: 8 additions & 57 deletions src/envs/openspiel_env/server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,11 @@
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

# Multi-stage build for OpenSpiel + OpenEnv
# Stage 1: Build OpenSpiel C++ bindings
# Using Python 3.11 to match envtorch-base
FROM python:3.11 AS openspiel-builder

# Avoid interactive prompts during build
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
clang \
cmake \
curl \
git \
sudo \
&& rm -rf /var/lib/apt/lists/*

# Set up OpenSpiel build directory
RUN mkdir /repo
WORKDIR /repo

# Clone OpenSpiel
RUN git clone https://github.com/google-deepmind/open_spiel.git .

# Run OpenSpiel's installation script (downloads C++ dependencies)
RUN ./install.sh

# Install Python dependencies
RUN pip3 install --no-cache-dir --upgrade setuptools testresources importlib_metadata
RUN pip3 install --no-cache-dir --upgrade -r requirements.txt cmake

# Build OpenSpiel with Python 3.11
RUN mkdir -p build
WORKDIR /repo/build
RUN cmake -DPython3_EXECUTABLE=$(which python3) -DCMAKE_CXX_COMPILER=$(which clang++) ../open_spiel
RUN make -j$(nproc) pyspiel

# Stage 2: Runtime image using published openenv-base
# Uses the standardized base image from GitHub Container Registry
# See: https://github.com/meta-pytorch/OpenEnv/pkgs/container/openenv-base
FROM ghcr.io/meta-pytorch/openenv-base:latest

# Copy OpenSpiel build artifacts from builder
RUN mkdir -p /repo
COPY --from=openspiel-builder /repo /repo

# Install OpenSpiel Python requirements in runtime
WORKDIR /repo
RUN pip3 install --no-cache-dir --upgrade -r requirements.txt

# Set Python path for OpenSpiel
ENV PYTHONPATH=/repo:/repo/build/python:${PYTHONPATH}
# Use the pre-built OpenSpiel base image
# Built from: docker build -t openspiel-base:latest -f src/envs/openspiel_env/server/Dockerfile.openspiel-base .
# In GitHub Actions, this is overridden to use the GHCR base image
ARG OPENSPIEL_BASE_IMAGE=openspiel-base:latest
FROM ${OPENSPIEL_BASE_IMAGE}

# Copy OpenEnv core (base image already set WORKDIR=/app)
WORKDIR /app
Expand All @@ -78,11 +29,11 @@ ENV OPENSPIEL_GAME=catch
ENV OPENSPIEL_AGENT_PLAYER=0
ENV OPENSPIEL_OPPONENT_POLICY=random

# Health check (curl is provided by envtorch-base)
# Health check (curl is provided by openenv-base)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

# Note: EXPOSE 8000 already set by envtorch-base
# Note: EXPOSE 8000 already set by openenv-base

# Run the FastAPI server (uvicorn installed by envtorch-base)
# Run the FastAPI server (uvicorn installed by openenv-base)
CMD ["uvicorn", "envs.openspiel_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"]
Loading