-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathDockerfile
More file actions
150 lines (123 loc) · 6.77 KB
/
Dockerfile
File metadata and controls
150 lines (123 loc) · 6.77 KB
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# =============================================================================
# sandboxed.sh — All-in-One Docker Image
# =============================================================================
# Multi-stage build: Rust backend + Next.js dashboard + runtime with AI CLIs
# Formerly known as "Open Agent"
#
# Build: docker build -t sandboxed-sh .
# Run: docker compose up
# =============================================================================
# ---------------------------------------------------------------------------
# Stage 1: Rust builder
# ---------------------------------------------------------------------------
FROM rust:1.88-bookworm AS rust-builder
WORKDIR /build
# Copy manifests first for better layer caching
COPY Cargo.toml ./
# Generate Cargo.lock if it doesn't exist in the context
RUN cargo generate-lockfile 2>/dev/null || true
# Create stub source so cargo can resolve deps
RUN mkdir -p src/bin \
&& echo "fn main() {}" > src/main.rs \
&& echo "fn main() {}" > src/bin/desktop_mcp.rs \
&& echo "fn main() {}" > src/bin/workspace_mcp.rs \
&& cargo build --release --lib 2>/dev/null || true \
&& cargo build --release 2>/dev/null || true
# Copy real source and build
COPY src/ src/
RUN cargo build --release --bin sandboxed-sh --bin desktop-mcp --bin workspace-mcp
# ---------------------------------------------------------------------------
# Stage 2: Dashboard builder
# ---------------------------------------------------------------------------
FROM oven/bun:1 AS dashboard-builder
WORKDIR /build/dashboard
COPY dashboard/package.json dashboard/bun.lock ./
RUN bun install --frozen-lockfile
COPY dashboard/ .
# Empty API URL — the Caddyfile proxies /api to the backend at runtime
ENV NEXT_PUBLIC_API_URL=""
# standalone output for Docker (not needed for Vercel)
ENV STANDALONE=true
RUN bun run build
# ---------------------------------------------------------------------------
# Stage 3: Runtime (Ubuntu 24.04 for native debootstrap support)
# ---------------------------------------------------------------------------
FROM ubuntu:24.04 AS runtime
ENV DEBIAN_FRONTEND=noninteractive
# -- Core system deps --------------------------------------------------------
RUN apt-get update && apt-get install -y --no-install-recommends \
git curl jq unzip openssh-client ca-certificates gnupg \
# nspawn / container workspaces
systemd-container debootstrap \
# Desktop automation
xvfb i3 x11-utils x11-xserver-utils xdotool scrot imagemagick \
tesseract-ocr at-spi2-core \
fonts-liberation fonts-dejavu fonts-noto \
# Chromium
chromium-browser \
&& rm -rf /var/lib/apt/lists/* \
# Add plucky (25.04) script for future Ubuntu releases
&& ln -sf gutsy /usr/share/debootstrap/scripts/plucky
# -- Node.js 20 (for Next.js standalone runtime) ------------------------------
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# -- Bun (preferred package manager for global installs + bunx) ---------------
RUN curl -fsSL https://bun.sh/install | bash \
&& install -m 0755 /root/.bun/bin/bun /usr/local/bin/bun \
&& install -m 0755 /root/.bun/bin/bunx /usr/local/bin/bunx
# -- Caddy (reverse proxy) ---------------------------------------------------
RUN curl -fsSL 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/ubuntu noble main" \
> /etc/apt/sources.list.d/caddy-stable.list \
&& apt-get update && apt-get install -y --no-install-recommends caddy \
&& rm -rf /var/lib/apt/lists/*
# -- Copy Rust binaries from builder -----------------------------------------
COPY --from=rust-builder /build/target/release/sandboxed-sh /usr/local/bin/sandboxed-sh
COPY --from=rust-builder /build/target/release/desktop-mcp /usr/local/bin/desktop-mcp
COPY --from=rust-builder /build/target/release/workspace-mcp /usr/local/bin/workspace-mcp
# -- Copy dashboard standalone build ------------------------------------------
COPY --from=dashboard-builder /build/dashboard/.next/standalone /opt/dashboard
COPY --from=dashboard-builder /build/dashboard/.next/static /opt/dashboard/.next/static
COPY --from=dashboard-builder /build/dashboard/public /opt/dashboard/public
# -- Pre-install AI harness CLIs (optional — agents still work if these fail) -
# Uses bun for global installs (faster than npm, and our preferred package manager)
ENV PATH="/root/.bun/bin:/root/.cache/.bun/bin:${PATH}"
RUN bun install -g @anthropic-ai/claude-code@latest \
&& echo "[docker] Claude Code CLI installed: $(claude --version 2>/dev/null || echo 'unknown')" \
|| echo "[docker] WARNING: Claude Code CLI install failed (will be installed on first mission)"
RUN curl -fsSL https://opencode.ai/install | bash -s -- --no-modify-path \
&& install -m 0755 /root/.opencode/bin/opencode /usr/local/bin/opencode \
&& echo "[docker] OpenCode CLI installed: $(opencode --version 2>/dev/null || echo 'unknown')" \
|| echo "[docker] WARNING: OpenCode CLI install failed (will be installed on first mission)"
RUN bun install -g @sourcegraph/amp@latest \
&& echo "[docker] Amp CLI installed: $(amp --version 2>/dev/null || echo 'unknown')" \
|| echo "[docker] WARNING: Amp CLI install failed (will be installed on first mission)"
# -- RTK (CLI output compressor for token savings) --
RUN RTK_ARCH=$(case "$(uname -m)" in aarch64|arm64) echo "aarch64";; *) echo "x86_64";; esac) \
&& curl -fsSL "https://github.com/rtk-ai/rtk/releases/latest/download/rtk-${RTK_ARCH}-unknown-linux-gnu.tar.gz" \
| tar xz -C /usr/local/bin rtk \
&& chmod +x /usr/local/bin/rtk \
&& echo "[docker] RTK installed: $(rtk --version 2>/dev/null || echo 'unknown')" \
|| echo "[docker] WARNING: RTK install failed (token savings will not be available)"
# -- i3 config (from install_desktop.sh) -------------------------------------
RUN mkdir -p /root/.config/i3
COPY docker/i3config /root/.config/i3/config
# -- Caddy config + entrypoint -----------------------------------------------
COPY docker/Caddyfile /etc/caddy/Caddyfile
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# -- Working directories ------------------------------------------------------
RUN mkdir -p /root/.sandboxed-sh /root/.claude /root/work/screenshots
# -- Environment defaults -----------------------------------------------------
ENV HOST=127.0.0.1 \
PORT=3000 \
WORKING_DIR=/root \
DEV_MODE=true \
DESKTOP_ENABLED=true \
DESKTOP_RESOLUTION=1920x1080 \
GIT_TERMINAL_PROMPT=0
EXPOSE 80
VOLUME ["/root/.sandboxed-sh", "/root/.claude"]
ENTRYPOINT ["/entrypoint.sh"]