Skip to content
Open
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,5 @@ output/

# local only scripts
start_tool_server.sh
docker/.stack.env.local
scripts/local/
135 changes: 135 additions & 0 deletions docker/.stack.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# ============================================================================
# ii-agent Local-Only Environment Configuration
# ============================================================================
# This configuration is for running ii-agent with LOCAL Docker sandboxes
# instead of E2B cloud. All data stays on your machine - suitable for
# privileged/NDA-protected data.
#
# Copy this file to .stack.env.local and configure the required values.
# ============================================================================

# ============================================================================
# SANDBOX PROVIDER (NEW - Docker instead of E2B)
# ============================================================================
# Use "docker" for local sandboxes or "e2b" for E2B cloud
SANDBOX_PROVIDER=docker

# Docker image to use for local sandboxes (build with: docker build -t ii-agent-sandbox:latest -f e2b.Dockerfile .)
SANDBOX_DOCKER_IMAGE=ii-agent-sandbox:latest

# Optional: Docker network for sandboxes to join (useful if MCP server is in a container)
# SANDBOX_DOCKER_NETWORK=ii-agent-network

# ============================================================================
# DATABASE CONFIGURATION
# ============================================================================
# Use a different port if native PostgreSQL is running on 5432
POSTGRES_PORT=5433
POSTGRES_USER=iiagent
POSTGRES_PASSWORD=iiagent
POSTGRES_DB=iiagentdev

# Database URLs for services (using internal docker hostname)
DATABASE_URL=postgresql://iiagent:iiagent@postgres:5432/iiagentdev

# Sandbox server database
SANDBOX_DB_NAME=ii_sandbox
SANDBOX_DATABASE_URL=postgresql+asyncpg://iiagent:iiagent@postgres:5432/ii_sandbox

# ============================================================================
# REDIS CONFIGURATION
# ============================================================================
REDIS_PORT=6379
REDIS_URL=redis://redis:6379/0
REDIS_SESSION_URL=redis://redis:6379/1

# ============================================================================
# SERVICE PORTS
# ============================================================================
FRONTEND_PORT=1420
BACKEND_PORT=8000
TOOL_SERVER_PORT=1236
SANDBOX_SERVER_PORT=8100

# Port for MCP server inside sandboxes
MCP_PORT=6060

# ============================================================================
# FRONTEND CONFIGURATION
# ============================================================================
FRONTEND_BUILD_MODE=production
VITE_API_URL=http://localhost:8000

# Disable Google OAuth for local setup (optional - set to enable)
VITE_GOOGLE_CLIENT_ID=

# Disable Stripe for local setup
VITE_STRIPE_PUBLISHABLE_KEY=

# Disable Sentry for local setup
VITE_SENTRY_DSN=

# ============================================================================
# AUTHENTICATION (Required)
# ============================================================================
# Generate with: openssl rand -hex 32
JWT_SECRET_KEY=CHANGE_ME_USE_openssl_rand_hex_32

# For local-only mode, you can use the demo user
# Enable demo mode to skip OAuth
DEMO_MODE=true

# ============================================================================
# LLM PROVIDER API KEYS (At least one required)
# ============================================================================
# OpenAI
OPENAI_API_KEY=

# Anthropic Claude
ANTHROPIC_API_KEY=

# Google Gemini
GEMINI_API_KEY=

# Groq
GROQ_API_KEY=

# Fireworks
FIREWORKS_API_KEY=

# OpenRouter (access to multiple models)
OPENROUTER_API_KEY=

# ============================================================================
# MCP SERVER CONFIGURATION (Optional - for your local MCP server)
# ============================================================================
# If you have a local MCP server running, configure it here
# This URL is accessible from within sandbox containers

# For MCP server running on host machine:
# MCP_SERVER_URL=http://host.docker.internal:6060

# For MCP server running in a Docker container on the same network:
# MCP_SERVER_URL=http://mcp-server:6060

# ============================================================================
# OPTIONAL SERVICES
# ============================================================================
# These are not required for local-only mode

# Image search (Serper)
# SERPER_API_KEY=

# Web search (Tavily)
# TAVILY_API_KEY=

# Cloud storage (not needed for local mode)
# GCS_BUCKET_NAME=
# GOOGLE_APPLICATION_CREDENTIALS=

# ============================================================================
# E2B CONFIGURATION (NOT NEEDED for local Docker mode)
# ============================================================================
# Leave these empty when using SANDBOX_PROVIDER=docker
# E2B_API_KEY=
# NGROK_AUTHTOKEN=
4 changes: 2 additions & 2 deletions docker/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ RUN fc-cache -fv
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project --no-dev
uv sync --locked --prerelease=allow --no-install-project --no-dev

# Install Playwright in a single layer
RUN uv run playwright install --with-deps chromium
Expand All @@ -39,7 +39,7 @@ RUN uv run playwright install --with-deps chromium
# Installing separately from its dependencies allows optimal layer caching
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev
uv sync --locked --prerelease=allow --no-dev

RUN chmod +x /app/start.sh
RUN chmod +x /app/scripts/run_sandbox_timeout_extension.sh
Expand Down
194 changes: 194 additions & 0 deletions docker/docker-compose.local-only.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Local-only docker-compose for ii-agent WITHOUT E2B cloud/ngrok
# This setup uses local Docker containers for sandboxes instead of E2B.
#
# Usage:
# 1. Build the sandbox image first:
# docker build -t ii-agent-sandbox:latest -f e2b.Dockerfile .
#
# 2. Copy and configure environment:
# cp docker/.stack.env.local.example docker/.stack.env.local
#
# 3. Start the stack:
# docker compose -f docker/docker-compose.local-only.yaml --env-file docker/.stack.env.local up -d
#
# This configuration:
# - Uses Docker provider instead of E2B (all data stays local)
# - No ngrok tunnel (no public exposure)
# - Suitable for privileged/NDA-protected data
# - Works in air-gapped environments

services:
postgres:
image: postgres:15
restart: unless-stopped
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_USER: ${POSTGRES_USER:-iiagent}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-iiagent}
POSTGRES_DB: ${POSTGRES_DB:-iiagentdev}
SANDBOX_DB_NAME: ${SANDBOX_DB_NAME:-ii_sandbox}
env_file:
- .stack.env.local
volumes:
- postgres-data-local:/var/lib/postgresql/data
- ./postgres-init/create-databases.sh:/docker-entrypoint-initdb.d/create-databases.sh:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-iiagent} -d ${POSTGRES_DB:-iiagentdev}"]
interval: 10s
timeout: 5s
retries: 5

redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "${REDIS_PORT:-6379}:6379"
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
volumes:
- redis-data-local:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5

frontend:
build:
context: ..
dockerfile: docker/frontend/Dockerfile
args:
BUILD_MODE: ${FRONTEND_BUILD_MODE:-production}
VITE_API_URL: ${VITE_API_URL:-http://localhost:8000}
VITE_GOOGLE_CLIENT_ID: ${VITE_GOOGLE_CLIENT_ID:-}
VITE_STRIPE_PUBLISHABLE_KEY: ${VITE_STRIPE_PUBLISHABLE_KEY:-}
VITE_SENTRY_DSN: ${VITE_SENTRY_DSN:-}
VITE_DISABLE_CHAT_MODE: ${VITE_DISABLE_CHAT_MODE:-false}
restart: unless-stopped
env_file:
- .stack.env.local
environment:
NODE_ENV: production
ports:
- "${FRONTEND_PORT:-1420}:1420"

tool-server:
build:
context: ..
dockerfile: docker/backend/Dockerfile
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
env_file:
- .stack.env.local
environment:
DATABASE_URL: ${DATABASE_URL}
entrypoint: ["/bin/sh", "-c"]
command:
- >-
exec uvicorn ii_tool.integrations.app.main:app
--host 0.0.0.0
--port 1236
ports:
- "${TOOL_SERVER_PORT:-1236}:1236"
volumes:
- ii-agent-filestore-local:/.ii_agent
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:1236/health || exit 1"]
interval: 15s
timeout: 5s
retries: 5

sandbox-server:
build:
context: ..
dockerfile: docker/backend/Dockerfile
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .stack.env.local
environment:
SANDBOX_DATABASE_URL: ${SANDBOX_DATABASE_URL}
SERVER_HOST: 0.0.0.0
SERVER_PORT: ${SANDBOX_SERVER_PORT:-8100}
REDIS_URL: redis://redis:6379/0
MCP_PORT: ${MCP_PORT:-6060}
# Use Docker provider instead of E2B
PROVIDER: docker
PROVIDER_TYPE: docker
SANDBOX_DOCKER_IMAGE: ${SANDBOX_DOCKER_IMAGE:-ii-agent-sandbox:latest}
# Network for sandbox containers - must match the compose project network
DOCKER_NETWORK: ${COMPOSE_PROJECT_NAME:-ii-agent-local}_default
# Enable local mode features (orphan cleanup, etc.)
LOCAL_MODE: "true"
ORPHAN_CLEANUP_ENABLED: "true"
ORPHAN_CLEANUP_INTERVAL_SECONDS: "300"
# Backend URL for session verification during orphan cleanup
BACKEND_URL: "http://backend:8000"
entrypoint: ["/bin/bash", "/app/start_sandbox_server.sh"]
ports:
- "${SANDBOX_SERVER_PORT:-8100}:8100"
# Mount Docker socket so sandbox-server can create containers
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- sandbox-workspaces:/tmp/ii-agent-sandboxes
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8100/health || exit 1"]
interval: 15s
timeout: 5s
retries: 5

backend:
build:
context: ..
dockerfile: docker/backend/Dockerfile
init: true
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
sandbox-server:
condition: service_started
tool-server:
condition: service_started
env_file:
- .stack.env.local
environment:
DATABASE_URL: ${DATABASE_URL}
SANDBOX_SERVER_URL: http://sandbox-server:${SANDBOX_SERVER_PORT:-8100}
# Tool server URL for backend-to-tool-server (Docker network)
TOOL_SERVER_URL: http://tool-server:1236
# Tool server URL for sandbox-to-tool-server (via host)
SANDBOX_TOOL_SERVER_URL: ${SANDBOX_TOOL_SERVER_URL:-http://host.docker.internal:1236}
REDIS_SESSION_URL: redis://redis:6379/1
# Use local filesystem storage instead of GCS
STORAGE_PROVIDER: local
LOCAL_STORAGE_PATH: /.ii_agent/storage
# Enable dev authentication (bypasses OAuth)
DEV_AUTH_ENABLED: "true"
ports:
- "${BACKEND_PORT:-8000}:8000"
volumes:
- ii-agent-filestore-local:/.ii_agent
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8000/health || exit 1"]
interval: 15s
timeout: 5s
retries: 5

volumes:
postgres-data-local:
redis-data-local:
ii-agent-filestore-local:
sandbox-workspaces:
10 changes: 10 additions & 0 deletions docker/docker-compose.local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Override file to disable ngrok for local-only development
# Usage: docker compose -f docker-compose.stack.yaml -f docker-compose.local.yaml up -d

services:
ngrok:
# Disable ngrok by setting an invalid entrypoint that exits immediately
entrypoint: ["/bin/sh", "-c", "echo 'ngrok disabled for local development' && exit 0"]
restart: "no"
profiles:
- disabled
6 changes: 5 additions & 1 deletion docker/docker-compose.stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ services:
SERVER_PORT: ${SANDBOX_SERVER_PORT:-8100}
REDIS_URL: redis://redis:6379/0
MCP_PORT: ${MCP_PORT:-6060}
DOCKER_NETWORK: docker_default
volumes:
- /var/run/docker.sock:/var/run/docker.sock
entrypoint: ["/bin/bash", "/app/start_sandbox_server.sh"]
ports:
- "${SANDBOX_SERVER_PORT:-8100}:8100"
Expand Down Expand Up @@ -136,7 +139,8 @@ services:
GOOGLE_APPLICATION_CREDENTIALS: /app/google-application-credentials.json
DATABASE_URL: ${DATABASE_URL}
SANDBOX_SERVER_URL: http://sandbox-server:${SANDBOX_SERVER_PORT:-8100}
TOOL_SERVER_URL: ${PUBLIC_TOOL_SERVER_URL}
# Internal URL for sandbox containers to reach tool-server (container-to-container)
TOOL_SERVER_URL: http://tool-server:${TOOL_SERVER_PORT:-1236}
REDIS_SESSION_URL: redis://redis:6379/1
ports:
- "${BACKEND_PORT:-8000}:8000"
Expand Down
Loading