|  | 
|  | 1 | +# syntax=docker/dockerfile:1 | 
|  | 2 | +# This is loosely based on `docker init`'s rust template. | 
|  | 3 | +# For a completely clean build, run something like this: | 
|  | 4 | +# ``` | 
|  | 5 | +# docker build --build-arg=PROFILE=dev --no-cache | 
|  | 6 | +# ``` | 
|  | 7 | + | 
|  | 8 | +############# | 
|  | 9 | +# Build stage | 
|  | 10 | +############# | 
|  | 11 | +# - `/src` is the repo directory. | 
|  | 12 | +# - `/artifacts` is $CARGO_TARGET_DIR. | 
|  | 13 | +# - `/output` is where the binaries go. | 
|  | 14 | + | 
|  | 15 | +ARG BUILD_BASE=rustlang/rust:nightly-bullseye-slim | 
|  | 16 | +FROM ${BUILD_BASE} AS build | 
|  | 17 | + | 
|  | 18 | +# Install build dependencies. | 
|  | 19 | +RUN apt-get update && apt-get install -y \ | 
|  | 20 | +    # for jemalloc | 
|  | 21 | +    libjemalloc-dev \ | 
|  | 22 | +    libjemalloc2 \ | 
|  | 23 | +    make \ | 
|  | 24 | +    # for openssl | 
|  | 25 | +    libssl-dev \ | 
|  | 26 | +    pkg-config \ | 
|  | 27 | +    # clean the image | 
|  | 28 | +    && rm -rf /var/lib/apt/lists/* | 
|  | 29 | + | 
|  | 30 | +ARG PROFILE=release | 
|  | 31 | +# forward the docker argument so that the script below can read it | 
|  | 32 | +ENV PROFILE=${PROFILE} | 
|  | 33 | + | 
|  | 34 | +# Build the application. | 
|  | 35 | +RUN \ | 
|  | 36 | +    # mount the repository so we don't have to COPY it in | 
|  | 37 | +    --mount=type=bind,source=.,target=/src \ | 
|  | 38 | +    # cache artifacts and the cargo registry to speed up subsequent builds | 
|  | 39 | +    --mount=type=cache,target=/artifacts \ | 
|  | 40 | +    --mount=type=cache,target=/usr/local/cargo/registry/ \ | 
|  | 41 | +    # run the build | 
|  | 42 | +    <<EOF | 
|  | 43 | +set -eux | 
|  | 44 | + | 
|  | 45 | +# need to change workdir instead of using --manifest-path because we need | 
|  | 46 | +# .cargo/config.toml | 
|  | 47 | +cd /src | 
|  | 48 | + | 
|  | 49 | +# use the cache mount | 
|  | 50 | +# (we will not be able to to write to e.g `/src/target` because it is bind-mounted) | 
|  | 51 | +CARGO_TARGET_DIR=/artifacts cargo build --locked "--profile=${PROFILE}" --all | 
|  | 52 | + | 
|  | 53 | +# narrow the find call to SUBDIR because if we just copy out all executables | 
|  | 54 | +# we will break the cache invariant | 
|  | 55 | +if [ "$PROFILE" = "dev" ]; then | 
|  | 56 | +    SUBDIR=debug # edge case | 
|  | 57 | +else | 
|  | 58 | +    SUBDIR=$PROFILE | 
|  | 59 | +fi | 
|  | 60 | + | 
|  | 61 | +# maxdepth because binaries are in the root | 
|  | 62 | +# - other folders contain build scripts etc. | 
|  | 63 | +mkdir /output | 
|  | 64 | +find "/artifacts/$SUBDIR" \ | 
|  | 65 | +    -maxdepth 1 \ | 
|  | 66 | +    -type f \ | 
|  | 67 | +    -executable \ | 
|  | 68 | +    -not -name '*.so' \ | 
|  | 69 | +    -exec cp '{}' /output \; \ | 
|  | 70 | +    -print | 
|  | 71 | + | 
|  | 72 | +EOF | 
|  | 73 | + | 
|  | 74 | +################## | 
|  | 75 | +# Final executable | 
|  | 76 | +################## | 
|  | 77 | +FROM debian:bullseye-slim AS final | 
|  | 78 | + | 
|  | 79 | +# Install runtime dependencies. | 
|  | 80 | +RUN apt-get update && apt-get install -y \ | 
|  | 81 | +    ca-certificates \ | 
|  | 82 | +    libjemalloc2 \ | 
|  | 83 | +    && rm -rf /var/lib/apt/lists/* | 
|  | 84 | + | 
|  | 85 | +# this keeps this build target agnostic to the build profile | 
|  | 86 | +COPY --from=build ["/output/rpc", "/output/leader", "/output/worker", "/output/verifier", "/usr/local/bin/"] | 
|  | 87 | + | 
|  | 88 | +# Create a non-privileged user that the app will run under. | 
|  | 89 | +# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user | 
|  | 90 | +ARG UID=10001 | 
|  | 91 | +RUN adduser \ | 
|  | 92 | +    --disabled-password \ | 
|  | 93 | +    --gecos "" \ | 
|  | 94 | +    --home "/nonexistent" \ | 
|  | 95 | +    --shell "/sbin/nologin" \ | 
|  | 96 | +    --no-create-home \ | 
|  | 97 | +    --uid "${UID}" \ | 
|  | 98 | +    user | 
|  | 99 | +USER user | 
|  | 100 | + | 
0 commit comments