forked from MinaProtocol/mina
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile-rosetta-hardcoded
353 lines (298 loc) · 13.8 KB
/
Dockerfile-rosetta-hardcoded
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#################################################################################################
# The "build-deps" stage
# - Installs all compilers/interpreters, tools, and OS packages on debian buster-slim
#################################################################################################
FROM debian@sha256:b527bec3708ee1fe2ffb4625d742a60bb45b06064e7c64a81b16550fe42710f5 AS build-deps
# Ocaml Version
ARG OCAML_VERSION=4.07
ARG OCAML_REVISION=.1
ARG OPAM_VERSION=2.0.7
# Golang version number used to detemine tarball name
ARG GO_VERSION=1.13.10
# Rust Version passed into rustup-init, can also be "stable", "nightly" or similar
ARG RUST_VERSION=1.45.2
# Rocksdb commit tag/branch to clone
ARG ROCKSDB_VERSION=v5.17.2
# OS package dependencies
# First add support for https and pkg-config for apt, then install everything else
# TODO: make sure this is the minimum compile-time deps
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install --yes \
build-essential \
libboost-dev \
libboost-program-options-dev \
libffi-dev \
libgmp-dev \
libgmp3-dev \
libjemalloc-dev \
libpq-dev \
libprocps-dev \
libsodium-dev \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libcap-dev \
pkg-config \
cmake \
m4 \
git \
curl \
sudo \
rsync \
unzip \
file
# Create opam user (for later) and give sudo to make opam happy
RUN adduser --uid 1000 --disabled-password --gecos '' opam \
&& passwd -l opam \
&& chown -R opam:opam /home/opam \
&& echo 'opam ALL=(ALL:ALL) NOPASSWD:ALL' > /etc/sudoers.d/opam \
&& chmod 440 /etc/sudoers.d/opam \
&& chown root:root /etc/sudoers.d/opam \
&& chmod 777 /tmp
# Opam install of a given OPAM_VERSION from github release
RUN curl -sL \
"https://github.com/ocaml/opam/releases/download/${OPAM_VERSION}/opam-${OPAM_VERSION}-x86_64-linux" \
-o /usr/bin/opam \
&& chmod +x /usr/bin/opam
# bubblewrap was disabled in other builds via the dockerfile-toolchain images, and in the default opam2 image.
# Importantly, this also allows the entire container to be built with a permissionless builder, avoiding docker-in-docker
# Keeping the exact install steps from the official opam image in case we want to re-enable in the future.
#RUN curl -fL https://github.com/projectatomic/bubblewrap/releases/download/v0.4.1/bubblewrap-0.4.1.tar.xz | \
# tar -xJ && \
# cd bubblewrap-0.4.1 && ./configure --prefix=/usr/local && make && sudo make install && \
# cd - && rm -rf bubblewrap-0.4.1
# Golang install of a given GO_VERSION (add -v for spam output of each file from the go dist)
# TODO: rosetta requires binary file downloads of this sort to be hashed + validated
RUN curl -s "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" | tar -xz -C /usr/lib/
# Rust install via rustup-init to a given RUST_VERSION
# TODO: rosetta requires binary file downloads of this sort to be hashed + validated
USER opam
RUN curl --proto '=https' --tlsv1.2 -sSf -o /tmp/rustup-init \
https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init \
&& chmod +x /tmp/rustup-init \
&& /tmp/rustup-init -y --default-toolchain "${RUST_VERSION}" --profile minimal \
&& rm /tmp/rustup-init
# For more about rustup-init see: https://github.com/rust-lang/rustup/blob/master/README.md
# As opposed to introducing another shell script here (that mostly just determines the platform)
# we just download the binary for the only platform we care about in this docker environment
USER root
# This builds and installs just the rocksdb static lib for us, and cleans up after itself
RUN git clone https://github.com/facebook/rocksdb \
--depth 1 --shallow-submodules \
-b "${ROCKSDB_VERSION}" /rocksdb \
&& make -C /rocksdb static_lib PORTABLE=1 -j$(nproc) \
&& cp /rocksdb/librocksdb.a /usr/local/lib/librocksdb_coda.a \
&& rm -rf /rocksdb \
&& strip -S /usr/local/lib/librocksdb_coda.a
###########################################################################################
# Initialize opam in a minimal fashion
###########################################################################################
# Set up environment for running as opam user
WORKDIR /home/opam
USER opam
ENV HOME /home/opam
# ENV OPAMYES 1
# Create the following user directory configs as the Opam user:
## Add go + rust to the path, unlimit the opam user,
## unlimit stack for future shells that might use spacetime,
## disable ipv6
## disable sandboxing to allow unprivledged builds
RUN mkdir --mode=700 ~/.gnupg \
&& echo 'export PATH="$PATH:/usr/lib/go/bin:$HOME/.cargo/bin"' >> ~/.bashrc \
&& echo 'ulimit -s unlimited' >> ~/.bashrc \
&& echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf
# Ocaml install of a given OCAML_VERSION via opam switch
# additionally initializes opam with sandboxing disabled, as we did not install bubblewrap above.
RUN git clone \
git://github.com/ocaml/opam-repository \
--depth 1 \
/home/opam/opam-repository \
&& opam init --disable-sandboxing -k git -a ~/opam-repository --bare \
&& opam switch create "${OCAML_VERSION}" "ocaml-base-compiler.${OCAML_VERSION}${OCAML_REVISION}" \
&& opam switch "${OCAML_VERSION}"
# Alternate variants for 4.07 that are included in the official opam image
# opam switch create 4.07+afl ocaml-variants.4.07.1+afl && \
# opam switch create 4.07+flambda ocaml-variants.4.07.1+flambda && \
# opam switch create 4.07+default-unsafe-string ocaml-variants.4.07.1+default-unsafe-string && \
# opam switch create 4.07+force-safe-string ocaml-variants.4.07.1+force-safe-string && \
#################################################################################################
# The "opam-deps" Stage
# - Continues from the build-deps image
# - Installs all opam dependencies and pins from coda's github
# - Includes the entire coda codebase and submodules in "${CODA_DIR}" (must be writable by opam user)
# - Largely mirrors/replaces ./scripts/setup-opam.sh
#################################################################################################
FROM build-deps AS opam-deps
# location of repo used for pins and external package commits
ARG CODA_DIR=coda
# branch to checkout on first clone (this will be the only availible branch in the container)
# can also be a tagged release
# TODO: change this to two distinct variables, one for opam/dependency clone
# and a distinct one for the coda codebase in the next stage
ARG OPAM_BRANCH=rosetta/debug-v1.1.3
# location of external packages
ARG EXTERNAL_PKG_DIR=$CODA_DIR/src/external
# don't keep sources, to force reinstall of pinned packages from Coda sources
# and to keep Docker image reasonable size
ENV OPAMKEEPBUILDDIR false
ENV OPAMREUSEBUILDDIR false
# git will clone into an empty dir, but this also helps us set the workdir in advance
RUN git clone \
-b "${OPAM_BRANCH}" \
--depth 1 \
--shallow-submodules \
--recurse-submodules \
https://github.com/CodaProtocol/coda ${HOME}/${CODA_DIR}
WORKDIR $HOME/$CODA_DIR
ENV OPAMYES 1
# TODO: handle this opam work without cloning the full repository (directly pull src/opam.export)
# TODO: handle uri's build failure in a more flexible manner
# Installs uri.2.2.1 and its dependencies so that build succeeds, then installs the rest of the deps
RUN opam install \
$(scripts/select-opam-deps.sh \
uri \
base \
stdio \
ppx_sexp_conv \
ppxlib \
ocaml-compiler-libs \
ocaml-migrate-parsetree \
dune \
ocamlfind \
base-bytes \
ppx_derivers \
re \
result \
stringext) \
&& opam switch import src/opam.export
# TODO: Get pins from a script that can be easily updated if more pins are needed
# Would be really nice to pull this script, the git submodules, and src/opam.export exclusively in this stage
RUN eval $(opam config env) \
&& opam pin add src/external/ocaml-extlib \
&& opam pin add src/external/ocaml-sodium \
&& opam pin add src/external/rpc_parallel \
&& opam pin add src/external/async_kernel \
&& opam pin add src/external/coda_base58 \
&& opam pin add src/external/graphql_ppx \
&& opam clean --logs -cs
#################################################################################################
# The "builder" Stage
# - builds coda and any other binaries required to run a node
# - should not include any data related to joining a specific network, only the node software itself
#################################################################################################
FROM opam-deps AS builder
# Use --build-arg "DUNE_PROFILE=dev" to build a dev image or for CI
ARG DUNE_PROFILE=dev
# branch to checkout on first clone (this will be the only availible branch in the container)
# can also be a tagged release
# TODO: change this to two distinct variables, one for opam/dependency clone
# and a distinct one for the coda codebase in the next stage
ARG CODA_BRANCH=rosetta/debug-v1.1.4
# location of repo used for pins and external package commits
ARG CODA_DIR=coda
ENV PATH "$PATH:/usr/lib/go/bin:$HOME/.cargo/bin"
# git will clone into an empty dir, but this also helps us set the workdir in advance
RUN cd $HOME && rm -rf $HOME/${CODA_DIR} \
&& git clone \
-b "${CODA_BRANCH}" \
--depth 1 \
--shallow-submodules \
--recurse-submodules \
https://github.com/CodaProtocol/coda ${HOME}/${CODA_DIR}
WORKDIR $HOME/${CODA_DIR}
# Build libp2p_helper and clear go module caches
# Could maybe also delete go during this step / build it as part of the deps stage?
RUN git pull \
&& cd src/app/libp2p_helper/src \
&& go mod download \
&& cd generate_methodidx \
&& go build -o ${HOME}/app/generate_methodidx \
&& cd ../libp2p_helper \
&& go build -o ${HOME}/app/libp2p_helper \
&& go clean --cache --modcache --testcache -r
# Make rosetta-crucial components and the generate_keypair tool
RUN eval $(opam config env) \
&& dune build --profile=${DUNE_PROFILE} \
src/app/generate_keypair/generate_keypair.exe \
src/app/cli/src/mina.exe \
src/app/archive/archive.exe \
src/app/rosetta/rosetta.exe \
src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe \
src/app/generate_keypair/generate_keypair.exe \
src/app/rosetta/test-agent/agent.exe \
src/app/rosetta/ocaml-signer/signer.exe \
&& _build/default/src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe \
--config-file src/app/rosetta/demo-config.json \
--genesis-dir ${HOME}/demo-genesis \
&& mv _build/default/src/app $HOME/app \
&& rm -rf _build
# TODO: consider making a coda-rosetta package with the minimum coda binaries/configs for rosetta.
# Right now make deb is overkill
#RUN eval $(opam config env) && make deb
#################################################################################################
# The "production" Stage
# - sets up the final container with built binaries and a running postgresql archive node setup
#################################################################################################
FROM debian@sha256:b527bec3708ee1fe2ffb4625d742a60bb45b06064e7c64a81b16550fe42710f5 AS production
ARG POSTGRES_DATA_DIR=/data/postgresql
ARG CODA_DAEMON_PORT=10101
ARG CODA_CONFIG_DIR=/root/.mina-config
# Sample public key for use in dev profile / demo mode genesis block
ARG PK=B62qrPN5Y5yq8kGE3FbVKbGTdTAJNdtNtB5sNVpxyRwWGcDEhpMzc8g
ENV DEBIAN_FRONTEND noninteractive
# Dependencies
# buster-slim configures apt to not store any cache, so no need to rm it
# TODO: make sure this is the minimum runtime deps
RUN apt-get -y update \
&& apt -y install \
curl \
ca-certificates \
dnsutils \
dumb-init \
libffi6 \
libgmp10 \
libgomp1 \
libjemalloc-dev \
libssl1.1 \
postgresql \
postgresql-contrib \
tzdata
# Make all directories for configuration and empty s3 cache dirs
RUN mkdir -p /tmp/s3_cache_dir \
&& mkdir -p /tmp/coda_cache_dir \
&& mkdir -p ${POSTGRES_DATA_DIR} \
&& chown postgres ${POSTGRES_DATA_DIR}
COPY --from=builder /home/opam/app/* /coda-bin/
COPY --from=builder /home/opam/coda/src/app /app
COPY --from=builder /home/opam/coda/src/app/rosetta/config.json /data/config.json
# all s3-cached files will be downloaded as needed at runtime
# Uncomment these to optimize start up time at the expense of image size
# COPY --from=builder /tmp/s3_cache_dir /tmp/s3_cache_dir
# COPY --from=builder /tmp/coda_cache_dir /tmp/coda_cache_dir
# Set up coda config dir with demo mode keys and genesis
COPY --from=builder /home/opam/demo-genesis ${CODA_CONFIG_DIR}/demo-genesis
COPY --from=builder /home/opam/coda/src/app/rosetta/demo-config.json ${CODA_CONFIG_DIR}/daemon.json
RUN mkdir -p --mode=700 ${CODA_CONFIG_DIR}/wallets/store/ \
&& echo "$PK" > ${CODA_CONFIG_DIR}/wallets/store/$PK.pub \
&& echo '{"box_primitive":"xsalsa20poly1305","pw_primitive":"argon2i","nonce":"8jGuTAxw3zxtWasVqcD1H6rEojHLS1yJmG3aHHd","pwsalt":"AiUCrMJ6243h3TBmZ2rqt3Voim1Y","pwdiff":[134217728,6],"ciphertext":"DbAy736GqEKWe9NQWT4yaejiZUo9dJ6rsK7cpS43APuEf5AH1Qw6xb1s35z8D2akyLJBrUr6m"}' \
> ${CODA_CONFIG_DIR}/wallets/store/${PK} \
&& chmod go-rwx ${CODA_CONFIG_DIR}/wallets/store/${PK}
USER postgres
# TODO: use POSTGRES_DATA_DIR variable more consistently and ensure proper escaping
# TODO: move this to a more useful and easy to maintain script in the rosetta directory for this purpose
RUN pg_dropcluster --stop 11 main \
&& pg_createcluster --start 11 -d ${POSTGRES_DATA_DIR} main \
&& echo "data_directory = '/data/postgresql'" >> /etc/postgresql/11/main/postgresql.conf \
&& echo "listen_addresses='*'" >> /etc/postgresql/11/main/postgresql.conf \
&& echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/11/main/pg_hba.conf \
&& /etc/init.d/postgresql start \
&& psql --command "CREATE USER pguser WITH SUPERUSER PASSWORD 'pguser';" \
&& createdb -O pguser archiver \
&& psql postgresql://pguser:pguser@localhost:5432/archiver -f /app/archive/create_schema.sql
ENV USER pguser
USER root
WORKDIR /app/rosetta
EXPOSE 3087
EXPOSE $CODA_DAEMON_PORT
ENTRYPOINT ["bash", "./docker-start.sh"]