forked from starkware-libs/papyrus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile
97 lines (78 loc) · 3.76 KB
/
Dockerfile
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
86
87
88
89
90
91
92
93
94
95
96
97
# We split the Dockerfile into two stages:
# Stage 1: We copy all the Cargo.toml files and create empty lib.rs files.
# Stage 2:
# * We copy the files from the first stage
# * We compile all the crates.
# * We copy the rest of the files and compile again.
# The reason we compile twice is to allow caching for the first compilation (that compiles all the
# dependency crates) if no Cargo.toml files were changed.
# The reason we split it into two stages is to first copy all the files and then erase all
# non-Cargo.toml files. This way, non-Cargo.toml files won't affect the cache of the second stage
# (For more on docker stages, read https://docs.docker.com/build/building/multi-stage/).
FROM rust:1.75 AS copy_toml
COPY crates/ /app/crates/
COPY Cargo.toml /app/
WORKDIR /app/
# Erase all non-Cargo.toml files.
RUN find /app \! -name "Cargo.toml" -type f -delete ; \
find /app -empty -type d -delete; \
# Create empty lib.rs files.
# In order for cargo init to work, we need to not have a Cargo.toml file. In each crate, we rename
# Cargo.toml to another name and after running `cargo init` we override the auto-generated
# Cargo.toml with the original.
mv Cargo.toml _Cargo.toml && \
# TODO: Consider moving to a script.
for dir in crates/*; do \
if [ -f "$dir/Cargo.toml" ]; then \
mv $dir/Cargo.toml $dir/_Cargo.toml \
&& cargo init --lib --vcs none $dir \
&& mv -f $dir/_Cargo.toml $dir/Cargo.toml; \
else \
for subdir in $dir/*; do \
mv $subdir/Cargo.toml $subdir/_Cargo.toml \
&& cargo init --lib --vcs none $subdir \
&& mv -f $subdir/_Cargo.toml $subdir/Cargo.toml; \
done; \
fi; \
done && \
mv _Cargo.toml Cargo.toml
COPY Cargo.lock /app/
# Starting a new stage so that the first build layer will be cached if a non-Cargo.toml file was
# changed.
# Use this image to compile the project to an alpine compatible binary.
FROM clux/muslrust:1.75.0-stable AS builder
WORKDIR /app/
RUN apt update && apt install -y clang unzip
ENV PROTOC_VERSION=25.1
RUN curl -L "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/protoc-$PROTOC_VERSION-linux-x86_64.zip" -o protoc.zip && unzip ./protoc.zip -d $HOME/.local && rm ./protoc.zip
ENV PROTOC=/root/.local/bin/protoc
# Copy all the files from the previous stage (which are Cargo.toml and empty lib.rs files).
COPY --from=copy_toml /app .
# Add the proc_macro code since cargo init puts autogenerated code in lib.rs file that breaks the build.
COPY crates/papyrus_proc_macros /app/crates/papyrus_proc_macros
RUN rustup target add x86_64-unknown-linux-musl && \
CARGO_INCREMENTAL=0 cargo build --target x86_64-unknown-linux-musl --release --package papyrus_node
# Copy the rest of the files.
COPY crates/ /app/crates
# Touching the lib.rs files to mark them for re-compilation. Then re-compile now that all the source
# code is available
RUN touch crates/*/src/lib.rs; \
CARGO_INCREMENTAL=0 cargo build --release --package papyrus_node --bin papyrus_node;
# Starting a new stage so that the final image will contain only the executable.
FROM alpine:3.17.0 AS papyrus_node
ENV ID=1000
WORKDIR /app
# Copy the node executable and its config.
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/papyrus_node /app/target/release/papyrus_node
COPY config/ /app/config
RUN set -ex; \
apk update; \
apk add --no-cache tini; \
mkdir data
RUN set -ex; \
addgroup --gid ${ID} papyrus; \
adduser --ingroup $(getent group ${ID} | cut -d: -f1) --uid ${ID} --gecos "" --disabled-password --home /app papyrus; \
chown -R papyrus:papyrus /app
EXPOSE 8080 8081
USER ${ID}
ENTRYPOINT ["/sbin/tini", "--", "/app/target/release/papyrus_node"]