diff --git a/Dockerfile b/Dockerfile index 6c63c6b08a..88ca264d5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,71 +1,78 @@ # syntax=docker/dockerfile:1.12 -FROM ubuntu:jammy AS final -LABEL name=slither \ - src="https://github.com/trailofbits/slither" \ - creator=trailofbits \ - dockerfile_maintenance=trailofbits \ - desc="Static Analyzer for Solidity" +# --- Stage 1: Build --- +FROM ubuntu:noble AS builder -RUN export DEBIAN_FRONTEND=noninteractive \ - && apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates curl git python3 python3-pip python3-venv \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 python3-venv curl \ + && curl -LsSf https://astral.sh/uv/install.sh \ + | UV_INSTALL_DIR=/usr/local/bin sh \ && rm -rf /var/lib/apt/lists/* -# Install uv if available for this architecture (amd64/arm64) -# uv doesn't support armv7, so those builds will use pip instead -RUN arch=$(uname -m) && \ - if [ "$arch" = "x86_64" ] || [ "$arch" = "aarch64" ]; then \ - curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR=/usr/local/bin sh; \ +# armv7 lacks prebuilt wheels for C extensions (bitarray, cytoolz, etc.) +RUN if [ "$(dpkg --print-architecture)" = "armhf" ]; then \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential python3-dev \ + && rm -rf /var/lib/apt/lists/*; \ fi -# improve compatibility with amd64 solc in non-amd64 environments (e.g. Docker Desktop on M1 Mac) -ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu -RUN if [ ! "$(uname -m)" = "x86_64" ]; then \ - export DEBIAN_FRONTEND=noninteractive \ - && apt-get update \ - && apt-get install -y --no-install-recommends libc6-amd64-cross \ - && rm -rf /var/lib/apt/lists/*; fi - -# Install build tools only on armv7 (needed for pip to compile wheels) -# amd64/arm64 use uv with pre-built wheels, so they don't need these -RUN arch=$(uname -m) && \ - if [ "$arch" = "armv7l" ]; then \ - export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install -y --no-install-recommends build-essential python3-dev && \ - rm -rf /var/lib/apt/lists/*; \ - fi +ENV UV_LINK_MODE=copy \ + UV_COMPILE_BYTECODE=1 \ + UV_PYTHON_DOWNLOADS=never \ + UV_PYTHON=python3.12 \ + UV_PROJECT_ENVIRONMENT=/app -RUN useradd -m slither -USER slither +WORKDIR /build -WORKDIR /home/slither/slither +# Layer 1: deps only (cached until pyproject.toml or uv.lock change) +RUN --mount=type=cache,target=/root/.cache \ + --mount=type=bind,source=uv.lock,target=uv.lock \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + --mount=type=bind,source=README.md,target=README.md \ + uv sync --locked --no-dev --no-install-project -# Copy dependency files first for layer caching -COPY --chown=slither:slither pyproject.toml uv.lock ./ +# Layer 2: install project (rebuilds on source changes) +COPY slither/ slither/ +COPY pyproject.toml uv.lock README.md ./ +RUN --mount=type=cache,target=/root/.cache \ + uv sync --locked --no-dev --no-editable -# Install dependencies - use uv if available (with lockfile), pip otherwise -RUN if command -v uv >/dev/null 2>&1; then \ - uv sync --frozen --no-install-project; \ - else \ - python3 -m venv .venv; \ - fi -# Copy source code -COPY --chown=slither:slither . . +# --- Stage 2: Runtime --- +FROM ubuntu:noble AS final + +LABEL org.opencontainers.image.title="slither" \ + org.opencontainers.image.description="Static Analyzer for Solidity" \ + org.opencontainers.image.url="https://github.com/crytic/slither" \ + org.opencontainers.image.source="https://github.com/crytic/slither" \ + org.opencontainers.image.vendor="Trail of Bits" \ + org.opencontainers.image.licenses="AGPL-3.0" -# Install the project itself and solc-select -RUN if command -v uv >/dev/null 2>&1; then \ - uv sync --frozen && \ - uv tool install solc-select; \ - else \ - . .venv/bin/activate && \ - pip install --no-cache-dir -e . solc-select; \ +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install -y --no-install-recommends python3 ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# Cross-arch solc compat (e.g. Docker Desktop on Apple Silicon) +ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu +RUN if [ "$(dpkg --print-architecture)" != "amd64" ]; then \ + export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install -y --no-install-recommends libc6-amd64-cross \ + && rm -rf /var/lib/apt/lists/*; \ fi -ENV PATH="/home/slither/slither/.venv/bin:/home/slither/.local/bin:${PATH}" +RUN useradd --create-home slither +USER slither +WORKDIR /home/slither + +# Copy the pre-built venv from builder +COPY --from=builder --chown=slither:slither /app /app +ENV PATH="/app/bin:${PATH}" +# Pre-download latest solc so the image is ready to use RUN solc-select use latest --always-install CMD ["/bin/bash"]