Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
102 lines (94 loc) · 5.29 KB
/
Copy pathDockerfile
File metadata and controls
102 lines (94 loc) · 5.29 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# syntax=docker/dockerfile:1
# Used by the `self-contained`/`previous-data` stages far below (routine rebuild path) — must be
# declared before the first FROM: Docker only allows an ARG referenced in a FROM instruction to
# be set this early (a second, scoped ARG re-declaration would be needed after FROM for use in
# RUN/COPY, but this one is only ever used in a FROM itself).
ARG PREVIOUS_IMAGE=registry.example.com/csl-on-demand:self-contained
FROM rust:1-alpine3.24 AS builder
RUN apk add --no-cache musl-dev
WORKDIR /build
COPY Cargo.toml Cargo.lock ./
COPY csl-service/Cargo.toml csl-service/Cargo.toml
COPY csl-client/Cargo.toml csl-client/Cargo.toml
RUN mkdir -p csl-service/src/bin csl-client/src/bin \
&& echo "fn main() {}" > csl-service/src/main.rs \
&& echo "" > csl-service/src/lib.rs \
&& echo "fn main() {}" > csl-service/src/bin/csl-ingest.rs \
&& echo "" > csl-client/src/lib.rs \
&& echo "fn main() {}" > csl-client/src/bin/csl-fetch.rs \
&& cargo build --release --package csl-service \
&& rm -rf csl-service/src csl-client/src
COPY csl-service/src csl-service/src
RUN touch csl-service/src/main.rs csl-service/src/lib.rs csl-service/src/bin/csl-ingest.rs \
&& cargo build --release --package csl-service
FROM alpine:3.24 AS runtime
# Both binaries ship in the same image: csl-service (the long-running HTTP
# origin) and csl-ingest (the offline tool that populates CSL_RESOURCES from
# a source directory/zip — see ../README.md "Storage"). Ingestion is
# deliberately NOT run as part of this default target: baking GBs of model
# data into the image itself would make it huge and slow to push/pull for
# no benefit — run `csl-ingest` once against a mounted volume instead (see
# compose.yml's `csl-ingest` service, or the `self-contained` target below
# for an image that bakes the data in).
COPY --from=builder /build/target/release/csl-service /usr/local/bin/csl-service
COPY --from=builder /build/target/release/csl-ingest /usr/local/bin/csl-ingest
ENV CSL_RESOURCES=/csl \
CSL_PATH_PREFIX=/csl \
CSL_BIND=0.0.0.0:8080 \
RUST_LOG=info
EXPOSE 8080
VOLUME ["/csl"]
CMD ["csl-service"]
# Opt-in, self-contained variant: bakes a CSL source tree into /csl at build
# time so the container serves immediately behind a plain nginx reverse
# proxy, no separate `csl-ingest` step or volume needed. Two ways to
# populate /csl, because ingesting is expensive (a full model library is
# GBs and slow to clone/ingest) while `csl-ingest`'s own output format
# (content-addressed blobs + manifests) is completely decoupled from
# csl-service's code — a code-only release never needs to touch already-
# ingested data at all:
#
# 1. First-ever build, or the source model library itself changed: ingest
# from a source tree supplied as a *named build context* (not part of
# this repo, so it can't just live under the normal build context):
#
# docker buildx build --target self-contained \
# --build-context csl=/path/to/X-Plane/Resources \
# -t registry.example.com/csl-on-demand:self-contained .
#
# `/csl-src` is discarded in this stage (never becomes a layer in the
# final image beyond the ingested blobs/manifests it produces).
#
# 2. Routine rebuild after a csl-service/csl-ingest code change, model
# library unchanged: reuse the CURRENTLY PUBLISHED image's already-
# ingested /csl wholesale instead of re-ingesting — no source tree, no
# git clone, no re-running csl-ingest at all, just new binaries layered
# on unchanged data. This is the default (PREVIOUS_IMAGE already points
# at this repo's own published tag) and should be the normal path for
# every release that isn't also a model-library update:
#
# docker buildx build --target self-contained \
# -t registry.example.com/csl-on-demand:self-contained .
#
# Either way the image is still large — it contains the actual model data,
# so push/pull is slow. Use the default `runtime` target above instead
# unless you specifically need a single-container, no-volume deployment.
FROM ${PREVIOUS_IMAGE} AS previous-data
FROM runtime AS self-contained-from-source
RUN --mount=type=bind,from=csl,target=/csl-src \
csl-ingest /csl /csl-src
FROM runtime AS self-contained
COPY --from=previous-data /csl /csl
# One-time reformat of whatever `previous-data` already had on disk: `manifest.rs`'s
# `write`/`write_sync`/`merge_and_write_assets_sync` now serialize compact JSON going forward
# (no reader ever needed the indentation — these files are only read back by `load`/`load_all`
# at startup, never hand-edited or served directly), but that only affects *future*
# `csl-ingest` runs. This "reuse previous data" path never re-runs `csl-ingest` at all, so
# whatever `PREVIOUS_IMAGE` already wrote (possibly pretty-printed, from before that fix)
# would otherwise be copied here verbatim. `jq -c` is a temporary build-time tool, not something
# `csl-service` itself depends on at runtime — installed and immediately removed in the same
# layer so it doesn't linger in the final image.
RUN apk add --no-cache --virtual .reformat-deps jq \
&& find /csl/manifests -name '*.json' -exec sh -c 'jq -c . "$1" > "$1.tmp" && mv "$1.tmp" "$1"' _ {} \; \
&& if [ -f /csl/assets.json ]; then jq -c . /csl/assets.json > /csl/assets.json.tmp && mv /csl/assets.json.tmp /csl/assets.json; fi \
&& apk del .reformat-deps