Skip to content
Draft
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
1 change: 1 addition & 0 deletions changes/9596.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dockerize the agent component with DooD (Docker-out-of-Docker) support, including krunner path sharing, REPL port binding fixes, and comprehensive Docker deployment documentation for all six components
70 changes: 70 additions & 0 deletions docker-compose.monorepo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,31 @@ services:
- "host.docker.internal:host-gateway"
restart: unless-stopped

backend-ai-agent:
image: backend.ai/agent:26.1.0rc1
container_name: backend-ai-agent
networks:
- half
ports:
- "6001:6001" # RPC (Manager -> Agent)
- "6003:6003" # Metrics/Internal API
# NOTE: Do NOT map service ports (30000-31000) here.
# In DooD mode, session containers bind these ports directly on the host.
# Mapping them to the agent container would cause port conflicts.
volumes:
- ./agent.toml:/etc/backend.ai/agent.toml:ro
- /var/run/docker.sock:/var/run/docker.sock # DooD: host Docker daemon
- /tmp/backend.ai/ipc:/tmp/backend.ai/ipc # IPC with session containers
- /tmp/scratches:/tmp/scratches # Scratch storage (must use host path)
- /tmp/backend-ai-krunner:/tmp/backend-ai-krunner # Shared krunner files for DooD
environment:
- PYTHONUNBUFFERED=1
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
depends_on:
- backend-ai-manager

backend-ai-webserver:
image: backend.ai/webserver:26.1.0rc1
container_name: backend-ai-webserver
Expand All @@ -35,6 +60,51 @@ services:
depends_on:
- backend-ai-manager

backend-ai-storage-proxy:
image: backend.ai/storage-proxy:26.1.0rc1
container_name: backend-ai-storage-proxy
networks:
- half
ports:
- "6021:6021" # Client API
- "6022:6022" # Manager API
volumes:
- ./storage-proxy.toml:/etc/backend.ai/storage-proxy.toml:ro
- ./vfroot:/vfroot
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped

backend-ai-appproxy-coordinator:
image: backend.ai/appproxy-coordinator:26.1.0rc1
container_name: backend-ai-appproxy-coordinator
networks:
- half
ports:
- "10200:10200"
volumes:
- ./proxy-coordinator.toml:/etc/backend.ai/proxy-coordinator.toml:ro
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
depends_on:
- backend-ai-manager

backend-ai-appproxy-worker:
image: backend.ai/appproxy-worker:26.1.0rc1
container_name: backend-ai-appproxy-worker
networks:
- half
ports:
- "10205-10300:10205-10300" # Port proxy range
volumes:
- ./proxy-worker.toml:/etc/backend.ai/proxy-worker.toml:ro
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
depends_on:
- backend-ai-appproxy-coordinator

networks:
half:
external: true
Expand Down
33 changes: 33 additions & 0 deletions docker/agent-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash
set -e

# DooD (Docker-out-of-Docker) krunner path setup
#
# In DooD mode, the agent creates session containers via the host Docker daemon.
# When the agent bind-mounts krunner files (runner, kernel, helpers) into session
# containers, Docker resolves the source paths on the HOST filesystem, not inside
# the agent container. To make these paths accessible from the host, we:
# 1. Copy krunner packages to a shared volume path (/tmp/backend-ai-krunner/)
# 2. Replace the originals with symlinks so importlib.resources.files() resolves
# to the shared path (via Path.resolve() in resolve_krunner_filepath)

KRUNNER_SHARED="/tmp/backend-ai-krunner"

if [ -d "$KRUNNER_SHARED" ]; then
SITE_PKG=$(python3 -c "import site; print(site.getsitepackages()[0])")
for pkg in runner kernel helpers; do
src="$SITE_PKG/ai/backend/$pkg"
dst="$KRUNNER_SHARED/$pkg"
if [ -d "$src" ] && [ ! -L "$src" ]; then
# First run: copy packages to shared volume and create symlinks
cp -r "$src" "$dst"
rm -rf "$src"
ln -s "$dst" "$src"
elif [ -L "$src" ]; then
# Already symlinked (container restart)
:
fi
done
fi

exec "$@"
37 changes: 37 additions & 0 deletions docker/backend.ai-agent.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ARG PYTHON_VERSION
FROM python:${PYTHON_VERSION} AS builder
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the full python:${PYTHON_VERSION} base for both stages significantly increases image size and pull time. If OS packages/build tooling aren’t required at runtime (beyond installing docker-ce-cli), consider switching the runtime stage to a slimmer variant (e.g., python:${PYTHON_VERSION}-slim) and only add the minimal apt packages needed for Docker CLI + certs.

Copilot uses AI. Check for mistakes.
ARG PKGVER
COPY dist /dist
COPY requirements.txt /requirements.txt
# Install dependencies from requirements.txt to respect version constraints
RUN pip wheel --wheel-dir=/wheels --no-cache-dir -r /requirements.txt
# Install backend.ai packages from /dist (these are not in requirements.txt or PyPI)
RUN pip wheel --wheel-dir=/wheels --no-cache-dir backend.ai-agent==${PKGVER} --find-links=/dist --no-deps

FROM python:${PYTHON_VERSION}
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the full python:${PYTHON_VERSION} base for both stages significantly increases image size and pull time. If OS packages/build tooling aren’t required at runtime (beyond installing docker-ce-cli), consider switching the runtime stage to a slimmer variant (e.g., python:${PYTHON_VERSION}-slim) and only add the minimal apt packages needed for Docker CLI + certs.

Copilot uses AI. Check for mistakes.
COPY --from=builder /wheels /wheels
COPY dist /dist
# Install all wheels and also look in /dist for backend.ai packages
RUN pip install --no-cache-dir --find-links=/dist /wheels/*.whl

# Install Docker CLI for DooD (Docker-out-of-Docker) operations
RUN install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
&& chmod a+r /etc/apt/keyrings/docker.asc \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends docker-ce-cli \
&& rm -rf /var/lib/apt/lists/*
Comment on lines +18 to +24
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image uses curl to fetch Docker’s GPG key but never installs curl (and may also be missing ca-certificates for HTTPS trust depending on the base image variant). This can cause the Dockerfile build to fail on bases where curl isn’t preinstalled. Install required packages (e.g., ca-certificates + curl, and if needed gnupg) before invoking curl, ideally in the same apt-get install step as docker-ce-cli.

Copilot uses AI. Check for mistakes.

# Create necessary directories
RUN mkdir -p /tmp/backend.ai/ipc /var/log/backend.ai /etc/backend.ai \
/var/lib/backend.ai

# Set working directory
WORKDIR /app

COPY docker/agent-entrypoint.sh /usr/local/bin/agent-entrypoint.sh
RUN chmod +x /usr/local/bin/agent-entrypoint.sh

ENTRYPOINT ["/usr/local/bin/agent-entrypoint.sh"]
CMD ["backend.ai", "ag", "start-server", "-f", "/etc/backend.ai/agent.toml"]
Loading