119 lines
6 KiB
Docker
119 lines
6 KiB
Docker
# OpenCode dev sandbox: rootless-Podman container with JDK 25, Node 24, pnpm,
|
|
# git, curl, and a hash-pinned build of OpenCode (github.com/anomalyco/opencode).
|
|
#
|
|
# Built as three stages: JDK and Node are pulled from their official upstream
|
|
# images and copied (not apt-installed) into a slim Debian final stage, to
|
|
# keep the image small while staying on a mainstream glibc distro.
|
|
|
|
# ---- Stage: JDK source ------------------------------------------------------
|
|
# JDK 24 is EOL (Adoptium stopped building it Sept 2025; no 24-jdk* images
|
|
# exist). JDK 25 is the current LTS. Built on Ubuntu Noble (glibc 2.39), which
|
|
# is older than Debian Trixie's glibc (2.40) below -- copying a binary linked
|
|
# against an older glibc into a newer-glibc environment is safe.
|
|
FROM eclipse-temurin:25-jdk-noble AS jdk-source
|
|
|
|
# ---- Stage: Node source ------------------------------------------------------
|
|
# Node 24 is the current Active LTS. Matched to the same Debian release as the
|
|
# final base so glibc versions are identical -- no compatibility risk at all.
|
|
FROM node:24-trixie-slim AS node-source
|
|
|
|
# ---- Final stage --------------------------------------------------------------
|
|
FROM debian:trixie-slim AS final
|
|
|
|
# Re-declared here: build ARGs don't cross stage boundaries implicitly.
|
|
# Auto-populated by podman/buildah from the build host's native platform on a
|
|
# plain `podman build` (no --platform needed) for same-arch builds, which
|
|
# covers building on either Apple Silicon or Intel Macs. Cross-arch builds
|
|
# would need an explicit --platform flag (out of scope for this project).
|
|
ARG TARGETARCH
|
|
|
|
# OpenCode version + per-arch SHA256 pins. Re-verified by hand against the
|
|
# actual release assets (curl + sha256sum), not just copied from a summary:
|
|
# curl -fsSL -o oc.tar.gz https://github.com/anomalyco/opencode/releases/download/v<ver>/opencode-linux-<x64|arm64>.tar.gz
|
|
# sha256sum oc.tar.gz
|
|
# Re-run this whenever OPENCODE_VERSION is bumped, and update the two hashes.
|
|
ARG OPENCODE_VERSION=1.18.32
|
|
ARG OPENCODE_SHA256_AMD64=3046e0404fdc60fb80307e7a47824ba07477364178a4d09baa8548496dd6d43b
|
|
ARG OPENCODE_SHA256_ARM64=568461b7d4d8c19865c97e9a1102e613049c6039d01fe772154de873c1865840
|
|
|
|
# pnpm version, installed via pnpm's own standalone script (not Corepack --
|
|
# the pnpm team doesn't recommend Corepack, and Node 25+ dropped bundling it).
|
|
ARG PNPM_VERSION=12.6.0
|
|
|
|
# ca-certificates : TLS roots for curl/git/npm/pnpm/JVM.
|
|
# fontconfig,
|
|
# libfreetype6 : Temurin's font subsystem needs these even headless.
|
|
# libstdc++6 : native runtime needed by libjvm.so and native Node addons.
|
|
# git, curl : required tools.
|
|
# tar : needed to extract the OpenCode release archive; not
|
|
# guaranteed present on a trimmed slim base.
|
|
# openssh-client : without it, `git clone git@...` silently fails.
|
|
RUN apt-get update && \
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
ca-certificates \
|
|
fontconfig \
|
|
libfreetype6 \
|
|
libstdc++6 \
|
|
git \
|
|
curl \
|
|
tar \
|
|
openssh-client && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# --- JDK / Node, copied from the source stages ---------------------------------
|
|
COPY --from=jdk-source /opt/java/openjdk /opt/java/openjdk
|
|
COPY --from=node-source /usr/local/bin /usr/local/bin
|
|
COPY --from=node-source /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
|
|
# /usr/local/bin is already on Debian's default PATH, so node/npm/npx need no
|
|
# extra PATH entry. JAVA_HOME/bin and PNPM_HOME are non-standard and need one.
|
|
ENV JAVA_HOME=/opt/java/openjdk
|
|
ENV PNPM_HOME=/opt/pnpm
|
|
ENV PATH="${JAVA_HOME}/bin:${PNPM_HOME}/bin:${PATH}"
|
|
|
|
# Fixed HOME: the container is run with --userns=keep-id, so the runtime UID
|
|
# is whatever host user invoked `podman run`, which has no /etc/passwd entry
|
|
# inside the image. A plain ENV HOME is unaffected by that UID mapping, so we
|
|
# pin it here and make it world-writable (sticky bit, like /tmp) so any mapped
|
|
# UID can use it.
|
|
ENV HOME=/home/dev
|
|
# Belt-and-suspenders on top of OpenCode's default (~/.config/opencode):
|
|
# OPENCODE_CONFIG_DIR is OpenCode's one confirmed config-location override.
|
|
ENV OPENCODE_CONFIG_DIR=/home/dev/.config/opencode
|
|
RUN mkdir -p /home/dev && chmod 1777 /home/dev
|
|
|
|
# pnpm: standalone installer, pinned version. SHELL must be set explicitly --
|
|
# the installer can't infer a shell type inside a minimal `RUN` environment
|
|
# with no interactive shell, and errors out (ERR_PNPM_UNKNOWN_SHELL) otherwise.
|
|
RUN curl -fsSL https://get.pnpm.io/install.sh | env PNPM_VERSION="${PNPM_VERSION}" SHELL=/bin/bash sh - && \
|
|
chmod -R a+rX "${PNPM_HOME}"
|
|
|
|
# OpenCode: arch-aware fetch, SHA256 verification, install.
|
|
# Asset naming uses "x64" for the amd64 arch, not "amd64".
|
|
# Confirmed layout: both tarballs contain the binary flat at top level as
|
|
# "opencode" (no subdirectory nesting).
|
|
RUN set -eu; \
|
|
case "$TARGETARCH" in \
|
|
amd64) OC_ARCH=x64; OC_SHA256="$OPENCODE_SHA256_AMD64" ;; \
|
|
arm64) OC_ARCH=arm64; OC_SHA256="$OPENCODE_SHA256_ARM64" ;; \
|
|
*) echo "ERROR: unsupported TARGETARCH='$TARGETARCH'" >&2; exit 1 ;; \
|
|
esac; \
|
|
curl -fsSL -o /tmp/opencode.tar.gz \
|
|
"https://github.com/anomalyco/opencode/releases/download/v${OPENCODE_VERSION}/opencode-linux-${OC_ARCH}.tar.gz"; \
|
|
printf '%s /tmp/opencode.tar.gz\n' "$OC_SHA256" | sha256sum -c -; \
|
|
mkdir -p /tmp/opencode-extract; \
|
|
tar -xzf /tmp/opencode.tar.gz -C /tmp/opencode-extract; \
|
|
install -m 0755 /tmp/opencode-extract/opencode /usr/local/bin/opencode; \
|
|
rm -rf /tmp/opencode.tar.gz /tmp/opencode-extract
|
|
|
|
# Build-time smoke tests: fail here, not at first `make opencode`.
|
|
RUN { ldd /usr/local/bin/opencode || true; } | tee /tmp/opencode-ldd.txt && \
|
|
if grep -qi "not found" /tmp/opencode-ldd.txt; then \
|
|
echo "ERROR: opencode binary has unresolved shared library dependencies" >&2; \
|
|
exit 1; \
|
|
fi && \
|
|
rm -f /tmp/opencode-ldd.txt
|
|
RUN java -version && node --version && pnpm --version && git --version && curl --version
|
|
|
|
WORKDIR /workspace
|
|
CMD ["opencode"]
|