-
Notifications
You must be signed in to change notification settings - Fork 168
Expand file tree
/
Copy pathDockerfile
More file actions
85 lines (71 loc) · 3.96 KB
/
Copy pathDockerfile
File metadata and controls
85 lines (71 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
FROM python:3.11-slim AS extractor
WORKDIR /app
COPY anneal/Cargo.toml ./
# Remove the [workspace] section so it can be built as a standalone package.
# Also inject tree-sitter dependencies used by doc_gen to cache them too.
RUN sed '1,2d' Cargo.toml > Cargo.toml.no_workspace && \
sed -i '/^\[dependencies\]$/a tree-sitter = "0.25"\ntree-sitter-lean4 = "0.2"' Cargo.toml.no_workspace
FROM ubuntu:24.04
# Relocate toolchains so that non-root developers can access and write to them
# when mapping UIDs.
ENV RUSTUP_HOME=/opt/rustup \
CARGO_HOME=/opt/cargo \
ELAN_HOME=/opt/elan \
PATH="/opt/cargo/bin:/opt/elan/bin:${PATH}"
# Install system dependencies as root.
# We add `graphviz` because it is required by `lake exe graph` to generate
# the dependency graph, and `python3` to run the pruning script.
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git curl build-essential pkg-config libssl-dev graphviz python3 && \
rm -rf /var/lib/apt/lists/*
# Create the mapped user and empty directories for toolchains.
# The `-l` flag is passed to `useradd` to avoid creating large sparse files
# for `lastlog` when building with large UIDs. Such sparse files interact
# poorly with Docker's `overlayfs` and can cause massive build delays.
ARG UID
ARG GID
RUN if [ -z "$UID" ]; then echo "UID build arg is required" && exit 1; fi && \
if [ -z "$GID" ]; then echo "GID build arg is required" && exit 1; fi && \
sed -i "s/^UID_MAX.*/UID_MAX $UID/" /etc/login.defs && \
groupadd -g $GID anneal && \
useradd -l -u $UID -g $GID -m anneal && \
mkdir /cache /opt/rustup /opt/cargo /opt/elan /workspace /opt/anneal_target /opt/anneal_toolchain && \
chown anneal:anneal /cache /opt/rustup /opt/cargo /opt/elan /workspace /opt/anneal_target /opt/anneal_toolchain
# Switch to non-root user for the rest of the build.
USER anneal
# Install Rust.
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --profile minimal
# Direct Anneal tests to write ephemeral integration targets here to leverage
# overlayfs.
ENV ANNEAL_INTEGRATION_TARGET_DIR=/cache/anneal_target
# In the image, we build dependencies into /opt/anneal_target. This ensures
# they are part of the image and available in CI matrix jobs.
# In local development, docker.sh overrides this to /cache/anneal_target
# via a volume mount, causing dependencies to be rebuilt once in the volume.
# This double-build is intentional to support both environments efficiently.
ENV CARGO_TARGET_DIR=/opt/anneal_target
WORKDIR /workspace/anneal
# Copy the workspace configuration (without workspace section) and lockfile.
COPY --from=extractor --chown=anneal:anneal /app/Cargo.toml.no_workspace ./Cargo.toml
COPY --chown=anneal:anneal anneal/Cargo.lock ./
# Copy source files needed to compile dependency-heavy modules.
COPY --chown=anneal:anneal anneal/src/setup.rs ./src/
COPY --chown=anneal:anneal exocrate/Cargo.toml /workspace/exocrate/Cargo.toml
COPY --chown=anneal:anneal exocrate/src /workspace/exocrate/src
COPY --chown=anneal:anneal anneal/build.rs ./
# Create a minimal `main.rs` and a dummy test file.
# This allows us to build dependencies in the image without copying the full
# source tree, avoiding unnecessary container rebuilds when source files change.
RUN echo 'mod setup; fn main() {}' > src/main.rs && \
mkdir tests && echo 'fn main() {}' > tests/integration.rs
# Build dependencies to cache them in the image.
# Note: We do not use `RUSTFLAGS='-Adead_code'` here (even though the dummy
# `main.rs` has dead code) because doing so would cause Cargo to invalidate
# this cache and rebuild everything when we later run commands *without*
# that flag (which is the default).
RUN cargo build && \
cargo build --tests
# Use a stable shared install root inside test containers. CI installs the
# Nix-built archive here before invoking tests or examples.
ENV ANNEAL_TOOLCHAIN_DIR=/opt/anneal_toolchain
# Ensure the integration target directory exists.
RUN mkdir -p /cache/anneal_target