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
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.git
.github
.vscode
.idea
node_modules
**/node_modules
dist
**/dist
.scratch
.opencode
forge-data
forge-llm-proxy-logs
forge-opencode-config-local
.venv
**/venv
__pycache__
**/__pycache__
*.log
.env
.env.*
!.env.example
9 changes: 9 additions & 0 deletions forge-llm-proxy/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git
.github
.vscode
.idea
__pycache__
**/__pycache__
.venv
**/venv
*.log
9 changes: 9 additions & 0 deletions forge-server/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git
.github
.vscode
.idea
__pycache__
**/__pycache__
.venv
**/venv
*.log
3 changes: 2 additions & 1 deletion forge-server/forge_server/api/runtime_errors_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ def _normalize_project_id(raw: str) -> str:
if _UUID_RE.match(raw):
return raw
try:
decoded = base64.b64decode(raw, validate=False).decode("utf-8", errors="ignore")
padded = raw + "=" * (-len(raw) % 4)
decoded = base64.b64decode(padded, validate=False).decode("utf-8", errors="ignore")
except Exception:
# Fall through — the UUID lookup will produce the original 422/500
# surface, which is still better than masking with a 404.
Expand Down
32 changes: 19 additions & 13 deletions forge-ui/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@
# - Better default caching headers + gzip out of the box.

# ── 1. Builder ───────────────────────────────────────────────────────────────
FROM oven/bun:1.3.14-alpine AS builder
FROM oven/bun:1.3.14 AS builder

# Build deps: forge-ui shares the opencode workspace tree, which pulls tree-
# sitter-* and other native modules compiled by node-gyp at install time.
# `make g++` alone is not enough — node-gyp also needs libc-dev, binutils,
# pkgconfig, etc. Alpine's `build-base` meta-package bundles all of them.
# Without this, bun reports "Failed to install N packages" and a cascade of
# FileNotFound errors that are symptoms, not causes.
RUN apk add --no-cache build-base python3 git
RUN apt-get update && apt-get install -y --no-install-recommends build-essential python3 git && rm -rf /var/lib/apt/lists/*

WORKDIR /build

Expand All @@ -45,11 +41,9 @@ COPY opencode/packages ./opencode/packages
COPY opencode/patches ./opencode/patches
COPY forge-ui/package.json ./forge-ui/

# Drop packages/desktop — its @forge/ui dep would resolve here (forge-ui is
# in context), but desktop also depends on @lydell/node-pty + Electron native
# bits we don't want in a static UI build. Same reasoning as in
# opencode/Dockerfile.forge.
RUN rm -rf opencode/packages/desktop
# Drop unused workspace packages (desktop, console, storybook, docs, web) so
# bun install only downloads dependencies actually needed for forge-ui.
RUN rm -rf opencode/packages/desktop opencode/packages/console opencode/packages/storybook opencode/packages/docs opencode/packages/web

# Strip bunfig.toml's minimumReleaseAge before install. See
# opencode/Dockerfile.forge for the full reasoning: the 3-day supply-chain
Expand All @@ -76,18 +70,30 @@ RUN --mount=type=tmpfs,target=/root/.bun/install/cache \

# Verify what's present so the log gives us a clear before/after for the
# packages bun complained about.
RUN cd opencode && for pkg in @ai-sdk/anthropic @smithy/eventstream-codec @shikijs/transformers minimatch; do if [ -d "node_modules/$pkg" ]; then echo "PRESENT $pkg"; else echo "MISSING $pkg"; fi; done
RUN cd opencode && for pkg in @ai-sdk/anthropic @smithy/eventstream-codec @shikijs/transformers minimatch; do \
if [ -d "node_modules/$pkg" ]; then \
echo "PRESENT $pkg"; \
else \
echo "MISSING $pkg"; \
fi; \
done

# Now copy forge-ui sources for the actual build step.
COPY forge-ui ./forge-ui

# Symlink opencode/node_modules into forge-ui and export bin path so vite and dependencies are found
RUN ln -s /build/opencode/node_modules /build/forge-ui/node_modules
ENV PATH="/build/opencode/node_modules/.bin:${PATH}"

# Vite reads VITE_* from the environment at BUILD time and inlines them into
# the static bundle. Pass them as build args so docker compose can override
# the dev defaults baked into forge-ui/.env.
ARG VITE_API_URL=http://api.forge.localhost
ARG VITE_PREVIEW_DOMAIN=preview.lvh.me
ARG VITE_OPENCODE_URL=http://opencode:7777
ENV VITE_API_URL=${VITE_API_URL} VITE_PREVIEW_DOMAIN=${VITE_PREVIEW_DOMAIN} VITE_OPENCODE_URL=${VITE_OPENCODE_URL}
ENV VITE_API_URL=${VITE_API_URL} \
VITE_PREVIEW_DOMAIN=${VITE_PREVIEW_DOMAIN} \
VITE_OPENCODE_URL=${VITE_OPENCODE_URL}

# Build. Vite reads index.html and ./src/, emits ./dist/.
RUN cd forge-ui && bun run build
Expand Down
11 changes: 11 additions & 0 deletions opencode/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.git
.github
.vscode
.idea
node_modules
**/node_modules
dist
**/dist
.scratch
.opencode
*.log
16 changes: 8 additions & 8 deletions opencode/Dockerfile.forge
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@
# that produces a single bundled file and ship that instead — same patch
# code, smaller runtime.

FROM oven/bun:1.3.14-alpine
FROM oven/bun:1.3.14

# Match the runtime tooling the upstream Dockerfile assumes plus python3
# (the ui-ux-pro-max skill's reasoning engine needs it for the design-
# system generator's scripts/search.py).
#
# build-base = gcc + g++ + make + libc-dev + binutils — required because
# build-essential = gcc + g++ + make + libc6-dev — required because
# tree-sitter-* packages ship native bindings compiled by node-gyp during
# `bun install`. Without it the install fails with:
# gyp ERR! stack Error: not found: make
RUN apk add --no-cache build-base python3 py3-pip ripgrep libgcc libstdc++ git curl jq
# `bun install`.
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential python3 python3-pip ripgrep git curl jq \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /opencode

Expand All @@ -37,7 +38,7 @@ COPY package.json bun.lock bunfig.toml turbo.json tsconfig.json ./
COPY packages ./packages
# patches/ holds bun patchedDependencies referenced in package.json.
# bun install reads them by the relative paths in patchedDependencies
# (e.g. patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch); missing files
# (e.g. patches/@silvia-odwyer-photon-node@0.3.4.patch); missing files
# fail the install. Copy them in BEFORE bun install.
COPY patches ./patches

Expand All @@ -48,8 +49,7 @@ COPY patches ./patches
# (workspace:*) which we don't ship here, so bun install fails resolving
# that dep — even after stripping ../forge-ui from the root workspaces.
# Strip both before install. Build-time only; source on disk is untouched.
RUN apk add --no-cache jq \
&& jq '.workspaces.packages |= map(select(. != "../forge-ui"))' package.json > package.tmp.json \
RUN jq '.workspaces.packages |= map(select(. != "../forge-ui"))' package.json > package.tmp.json \
&& mv package.tmp.json package.json \
&& rm -rf packages/desktop

Expand Down
8 changes: 4 additions & 4 deletions opencode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@
"@types/node": "catalog:"
},
"patchedDependencies": {
"@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch",
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
"@npmcli/agent@4.0.0": "patches/@npmcli-agent@4.0.0.patch",
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer-photon-node@0.3.4.patch",
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community-standard-openapi@0.2.9.patch",
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
"@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch"
"@ai-sdk/xai@3.0.82": "patches/@ai-sdk-xai@3.0.82.patch"
}
}
Loading