0d8ac4f24b
* feat(docker): official image with all runtime deps pre-installed
Multi-stage build using uv for the EvoScientist core + all messaging-channel
extras, plus Node.js 24 LTS (for npx-based MCP servers) and uv (for runtime
Python MCP installs) in the runtime layer. Runs as non-root user evosci,
with workspace, app data, and config (XDG_CONFIG_HOME) all consolidated
under a single /home/evosci/.evoscientist volume so a single mount
persists everything across container restarts.
Includes a docker-compose.yml starter, a build/push GitHub Actions
workflow targeting ghcr.io with multi-arch (amd64/arm64) and PR-only
build verification, a .dockerignore, and a new Docker section in the
README documenting mounts, derivation recipes for the unbundled stt /
oauth / TinyTeX extras, and proxy/cert handling expectations.
* fix(docker): pin trixie base + drop redundant python image
Switch builder and runtime from `python:3.11-slim-bookworm` to a single
`ghcr.io/astral-sh/uv:python3.11-trixie-slim` base — trixie drops several
CRITICAL vulnerabilities that bookworm carries today, and reusing the uv
image for runtime eliminates the separate `COPY --from=…/uv` line.
* chore(docker): pin GitHub Actions to commit SHAs in workflow
Replace mutable major-version tags with full commit SHAs (with the
corresponding semver tag in a trailing comment) so a compromised /
retagged action release can't silently change what runs in the publish
pipeline.
* chore(deps): enable Dependabot version updates for Dockerfile pins
Adds a weekly `docker` ecosystem that watches the Dockerfile's `FROM` /
`COPY --from=` references — including the ARG-bound `BASE_IMAGE` and
`NODE_IMAGE` digests — and opens one grouped PR per cadence bumping
both the @sha256 digest and the trailing version comment. This keeps
the otherwise-frozen pins flowing with Debian point releases and
upstream patches.
* fix(docker): use nodejs alias stage so NODE_IMAGE ARG actually resolves
`COPY --from=${NODE_IMAGE}` left the dollar-curly literal at parse time
under buildkit 29.x — it expands ARGs in `FROM` but reads `--from=` as a
static stage/image name. Introduce a tiny `FROM ${NODE_IMAGE} AS nodejs`
alias and `COPY --from=nodejs …` against it, which preserves the
ARG-driven Dependabot updates without tripping the parser.
* fix(docker): harden venv ownership and PATH ordering
- Drop `--chown` on the `/opt/venv` COPY so the venv stays root-owned.
The runtime user only needs read+execute (default Unix perms allow
that); making it user-owned let the agent rewrite its own
dependencies, which defeats the sandboxing premise. All persistent
agent state already lives under /home/evosci/.evoscientist/.
- Reorder PATH so /opt/venv/bin precedes the user-writable
UV_TOOL_BIN_DIR. Otherwise a stray binary dropped into the latter
(e.g. via `uv tool install`) could shadow the canonical
`evosci` / `python` / `pip` shipped with the image.
* docs: update README
* docs(docker): warn about non-root UID and `curl | sh` for derived images
- The image runs as `evosci` (UID 1000), so a host-side `./workspace`
bind mount fails if the host user has a different UID — same gotcha
that bites onboarding's `mcp.yaml` write. Add an !IMPORTANT block
with the two practical fixes (`chown -R 1000:1000` once, or
`--user "$(id -u):$(id -g)"` on each run).
- The TinyTeX derivation snippet pipes an unpinned remote installer
into `sh`. Add a one-line pointer to fetching a pinned release
tarball from `rstudio/tinytex-releases` for users who'd rather not
trust the upstream script blindly. The official installer is kept
as the default since that's what TinyTeX itself recommends.
* chore(docker): cancel in-flight workflow runs + flag iMessage as host-only
- Add `concurrency: cancel-in-progress: true` to the docker workflow
so successive pushes on the same ref supersede the prior run rather
than queueing in parallel — multi-arch buildx is the slowest job in
CI, no point burning minutes on superseded builds.
- Spell out that the docker image installs the `all-chanels` extra and
call out iMessage as a deliberate host-only exclusion: it requires
the `imsg` CLI bridging to macOS's Messages.app, which no Linux
container config can satisfy.
76 lines
2.6 KiB
Docker
76 lines
2.6 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
ARG BASE_IMAGE=ghcr.io/astral-sh/uv:python3.11-trixie-slim@sha256:7936cc6625ca04cafa6ecc3c2881ddfe90a747c55c74480cd4ac6ffad6a5af1e
|
|
ARG NODE_IMAGE=node:24-trixie-slim@sha256:735dd688da64d22ebd9dd374b3e7e5a874635668fd2a6ec20ca1f99264294086
|
|
|
|
FROM ${NODE_IMAGE} AS nodejs
|
|
|
|
# ---------- Builder ----------
|
|
FROM ${BASE_IMAGE} AS builder
|
|
|
|
ENV UV_COMPILE_BYTECODE=1 \
|
|
UV_LINK_MODE=copy \
|
|
UV_PYTHON_DOWNLOADS=never \
|
|
UV_PROJECT_ENVIRONMENT=/opt/venv
|
|
|
|
WORKDIR /src
|
|
|
|
COPY pyproject.toml uv.lock README.md ./
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-install-project --no-dev \
|
|
--extra all-channels
|
|
|
|
COPY EvoScientist ./EvoScientist
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-dev --no-editable \
|
|
--extra all-channels
|
|
|
|
# ---------- Runtime ----------
|
|
FROM ${BASE_IMAGE} AS runtime
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
git \
|
|
ca-certificates \
|
|
tini \
|
|
curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY --from=nodejs /usr/local/bin/node /usr/local/bin/node
|
|
COPY --from=nodejs /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
|
|
&& ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
|
|
|
|
ARG UID=1000
|
|
ARG GID=1000
|
|
RUN groupadd --gid ${GID} evosci \
|
|
&& useradd --uid ${UID} --gid ${GID} --create-home --shell /bin/bash evosci
|
|
|
|
COPY --from=builder /opt/venv /opt/venv
|
|
|
|
ENV PATH="/opt/venv/bin:/home/evosci/.evoscientist/.local/bin:${PATH}" \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
EVOSCIENTIST_WORKSPACE_DIR=/workspace \
|
|
EVOSCIENTIST_DATA_DIR=/home/evosci/.evoscientist \
|
|
XDG_CONFIG_HOME=/home/evosci/.evoscientist/.config \
|
|
UV_TOOL_DIR=/home/evosci/.evoscientist/.local/share/uv/tools \
|
|
UV_TOOL_BIN_DIR=/home/evosci/.evoscientist/.local/bin
|
|
|
|
RUN mkdir -p /workspace \
|
|
/home/evosci/.evoscientist/.config/evoscientist \
|
|
/home/evosci/.evoscientist/.local/bin \
|
|
/home/evosci/.evoscientist/.local/share/uv/tools \
|
|
&& chown -R ${UID}:${GID} /workspace /home/evosci
|
|
|
|
USER evosci
|
|
WORKDIR /workspace
|
|
|
|
LABEL org.opencontainers.image.title="EvoScientist" \
|
|
org.opencontainers.image.description="EvoScientist agent with core + all-channels dependencies pre-installed." \
|
|
org.opencontainers.image.source="https://github.com/EvoScientist/EvoScientist" \
|
|
org.opencontainers.image.documentation="https://github.com/EvoScientist/EvoScientist#-docker" \
|
|
org.opencontainers.image.licenses="Apache-2.0"
|
|
|
|
ENTRYPOINT ["tini", "--", "evosci"]
|