mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
The rename turned upstream's own CDN into mmdbcdn.insights.net, a name nobody serves, and four images fetched their GeoLite2 city database from it — each one failing the moment that layer ran. They now read the same DB-IP source the root Dockerfile already used, so there is ONE way to get this file; the decompressor follows the format (gzip, not brotli). Verified against the live URL: 200, and the stream gunzips.
109 lines
4.3 KiB
Docker
109 lines
4.3 KiB
Docker
# Dev sandbox image for isolated branch environments.
|
|
#
|
|
# Layers are ordered by change frequency — things that rarely change (system
|
|
# packages, toolchains) go first so they stay cached. COPY statements that
|
|
# reference repo files go last since they invalidate on every change.
|
|
|
|
FROM python:3.13.13-slim-bookworm@sha256:355bfa66770995d7e9a0da4b3473b44d0cb451f6b56f5615ad9c39e3c4eca03f
|
|
|
|
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
|
|
|
|
ENV NODE_VERSION=24.13.0 \
|
|
NODE_ENV=development \
|
|
RUSTUP_HOME=/usr/local/rustup \
|
|
CARGO_HOME=/usr/local/cargo \
|
|
PATH="/cache/python/bin:/usr/local/cargo/bin:$PATH" \
|
|
SHELL=/bin/bash \
|
|
UV_PROJECT_ENVIRONMENT=/cache/python
|
|
|
|
# --- Rarely changes: system packages ---
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
gzip \
|
|
build-essential \
|
|
cmake \
|
|
curl \
|
|
git \
|
|
jq \
|
|
libclang-dev \
|
|
libffi-dev \
|
|
libpq-dev \
|
|
libssl-dev \
|
|
libxml2-dev \
|
|
libxmlsec1-dev \
|
|
libxslt1-dev \
|
|
gosu \
|
|
openssh-server \
|
|
pkg-config \
|
|
postgresql-client \
|
|
protobuf-compiler \
|
|
sudo \
|
|
tmux \
|
|
unzip \
|
|
vim \
|
|
zlib1g-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Personal image layers run install snippets as the sandbox user.
|
|
# NOPASSWD sudo is available as an escape hatch for recipes that need
|
|
# system-wide install (apt-get, /usr writes). Prefer ~/.local for
|
|
# anything that can install per-user; reach for sudo when it can't.
|
|
RUN echo "sandbox ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/sandbox \
|
|
&& chmod 0440 /etc/sudoers.d/sandbox
|
|
|
|
# --- Rarely changes: Rust toolchain + sqlx-cli ---
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path \
|
|
&& chmod -R a+rwx /usr/local/cargo /usr/local/rustup
|
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,target=/tmp/cargo-build \
|
|
CARGO_TARGET_DIR=/tmp/cargo-build cargo install sqlx-cli --no-default-features --features postgres
|
|
|
|
# --- Rarely changes: Node.js ---
|
|
RUN ARCH=$(dpkg --print-architecture) && \
|
|
case "${ARCH}" in \
|
|
amd64) NODE_ARCH='x64';; \
|
|
arm64) NODE_ARCH='arm64';; \
|
|
*) echo "unsupported: ${ARCH}"; exit 1;; \
|
|
esac && \
|
|
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" \
|
|
| tar xJ -C /usr/local --strip-components=1 --no-same-owner
|
|
RUN corepack enable
|
|
|
|
# --- Rarely changes: prebuilt binaries ---
|
|
COPY --from=ghcr.io/astral-sh/uv:0.11.14 /uv /uvx /usr/local/bin/
|
|
COPY --from=datastore/datastore-server:26.6.1.1193 /usr/bin/datastore /usr/local/bin/datastore
|
|
RUN ln -s datastore /usr/local/bin/datastore-client
|
|
|
|
RUN ARCH=$(dpkg --print-architecture) && \
|
|
curl -fsSL "https://github.com/Insights/insights/releases/download/phrocs-1.0.2/phrocs-linux-${ARCH}" \
|
|
-o /usr/local/bin/phrocs && chmod +x /usr/local/bin/phrocs
|
|
|
|
RUN ARCH=$(dpkg --print-architecture) && \
|
|
curl -fsSL "https://github.com/redpanda-data/redpanda/releases/download/v25.1.9/rpk-linux-${ARCH}.zip" \
|
|
-o /tmp/rpk.zip && unzip -o /tmp/rpk.zip -d /usr/local/bin/ rpk && rm /tmp/rpk.zip
|
|
|
|
# --- Changes occasionally: npm global packages ---
|
|
RUN npm install -g @anthropic-ai/claude-code
|
|
|
|
# --- Rarely changes: GeoIP database (pre-decompressed, read directly at runtime) ---
|
|
# The stream lands with the shell's default mode; chmod so non-root users can
|
|
# read the symlink target from /workspace/share.
|
|
RUN mkdir -p /share && \
|
|
DBIP_MONTH=$(date +%Y-%m) && curl -sS -L --fail --retry 3 --retry-max-time 60 "https://download.db-ip.com/free/dbip-city-lite-${DBIP_MONTH}.mmdb.gz" | \
|
|
gunzip > /share/GeoLite2-City.mmdb && \
|
|
chmod 644 /share/GeoLite2-City.mmdb
|
|
|
|
# --- Static config ---
|
|
RUN echo 'export PATH="/cache/python/bin:/usr/local/cargo/bin:$PATH"' > /etc/profile.d/sandbox.sh
|
|
RUN printf 'set -g default-terminal "xterm-256color"\nset -g extended-keys on\nset -as terminal-features "xterm*:extkeys"\nset -g allow-passthrough on\n' > /etc/tmux.conf
|
|
RUN mkdir -p /cache/uv /cache/pnpm /cache/python /run/sshd \
|
|
&& chmod 777 /cache/uv /cache/pnpm /cache/python \
|
|
&& ssh-keygen -A
|
|
|
|
WORKDIR /workspace
|
|
|
|
# --- Changes often: entrypoint + sandbox tmux shim ---
|
|
COPY bin/sandbox-shims/tmux.sandbox.conf /etc/tmux.sandbox.conf
|
|
COPY --chmod=755 bin/sandbox-entrypoint.py /usr/local/bin/sandbox-entrypoint.py
|
|
|
|
ENTRYPOINT ["python3", "/usr/local/bin/sandbox-entrypoint.py"]
|