Repository navigation
Expand file tree
/
Copy pathDockerfile.web
More file actions
148 lines (128 loc) · 6.92 KB
/
Copy pathDockerfile.web
File metadata and controls
148 lines (128 loc) · 6.92 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
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
# syntax=docker/dockerfile:1.7
# ============================================
# AINS Web - Frontend Dockerfile
# ============================================
# Build context: project root directory
# Usage: docker build -f Dockerfile.web -t ains-web .
#
# Nginx configuration is COPY'd at build time as default.
# To override at runtime, mount nginx/default.conf as a volume
# (see docker-compose.yml).
FROM rust:1.92.0-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y \
curl \
pkg-config \
libssl-dev \
binaryen \
&& rm -rf /var/lib/apt/lists/*
# Install wasm32 target needed for Dioxus WASM compilation
RUN rustup target add wasm32-unknown-unknown
# Use the sparse registry with resilient network settings. Dependencies fetched
# below intentionally remain in a normal image layer: external BuildKit caches
# (including GHA) do not preserve cache-mount contents on a fresh builder, while
# the final dx build must have the complete Web-only dependency set offline.
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
ENV CARGO_HTTP_TIMEOUT=120
ENV CARGO_NET_RETRY=3
# Install dioxus-cli via cargo-binstall for pre-built binaries (much faster than cargo install).
ENV BINSTALL_VERSION=v1.10.22
ARG BINSTALL_SHA256=
RUN curl -L --proto '=https' --tlsv1.2 -sSf \
"https://github.com/cargo-bins/cargo-binstall/releases/download/${BINSTALL_VERSION}/cargo-binstall-$(uname -m)-unknown-linux-musl.tgz" \
-o /tmp/binstall.tgz && \
if [ -n "${BINSTALL_SHA256}" ]; then \
echo "${BINSTALL_SHA256} /tmp/binstall.tgz" | sha256sum -c -; \
else \
echo "WARNING: BINSTALL_SHA256 not set — skipping checksum verification."; \
fi && \
tar xzf /tmp/binstall.tgz -C /usr/local/cargo/bin && \
rm /tmp/binstall.tgz
RUN cargo binstall dioxus-cli --version 0.7.9 -y
# Install wasm-bindgen-cli at the EXACT version of the wasm-bindgen crate in Cargo.lock
# (0.2.126). Required because NO_DOWNLOADS=1 (set before `dx build` below) makes dioxus-cli
# resolve ALL tooling from PATH instead of downloading — dx does an exact version match on
# `wasm-bindgen --version`, so this MUST be kept in sync with the wasm-bindgen crate version.
RUN cargo binstall wasm-bindgen-cli --version 0.2.126 -y
# Install esbuild (required by dioxus-cli for web builds; NO_DOWNLOADS=1 prevents dx from
# downloading it automatically, so it must be pre-installed on PATH).
# Downloaded from npm registry for reliable version pinning and binary naming.
# SHA256 verified against the dist.integrity published by npm for the same version.
ENV ESBUILD_VERSION=0.28.1
RUN ARCH=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/') && \
curl -L --proto '=https' --tlsv1.2 -sSf \
"https://registry.npmjs.org/@esbuild/linux-${ARCH}/-/linux-${ARCH}-${ESBUILD_VERSION}.tgz" \
-o /tmp/esbuild.tgz && \
case "$ARCH" in \
x64) echo "9ed00ab5330c94386f3273eda99a1fb0e8f37cfd6cb5270e4ad2fe3527da3546 /tmp/esbuild.tgz" | sha256sum -c - ;; \
arm64) echo "2145e9e686c95ee47c1181f83f272f0ff95820e52d7736fdcd9eeb106fd6456a /tmp/esbuild.tgz" | sha256sum -c - ;; \
*) echo "Unsupported architecture: $ARCH"; exit 1 ;; \
esac && \
tar xzf /tmp/esbuild.tgz -C /tmp && \
mv /tmp/package/bin/esbuild /usr/local/bin/esbuild && \
chmod +x /usr/local/bin/esbuild && \
rm -rf /tmp/esbuild.tgz /tmp/package
# ── Stage the Docker-only Web/WASM workspace ──
# The production manifests intentionally exclude desktop, mobile, server,
# native-only, and test-only dependencies. dx 0.7.9 runs cargo metadata without
# a platform filter, so pruning only the root workspace members is insufficient.
COPY prod-build/web/Cargo.toml prod-build/web/Cargo.lock ./
COPY prod-build/web/manifests/web.toml ./app/web/Cargo.toml
COPY prod-build/web/manifests/ui.toml ./app/ui/Cargo.toml
COPY prod-build/web/manifests/client-api.toml ./app/client-api/Cargo.toml
COPY prod-build/web/manifests/rust-agent.toml ./crates/rust-agent/Cargo.toml
COPY prod-build/web/manifests/i18n.toml ./crates/i18n/Cargo.toml
COPY app/web/Dioxus.toml ./app/web/Dioxus.toml
# Create valid targets so dependency fetching stays cached independently from
# application source changes.
RUN for dir in app/web app/ui app/client-api crates/rust-agent crates/i18n; do \
mkdir -p "$dir/src"; \
done && \
echo 'fn main() {}' > app/web/src/main.rs && \
echo 'pub fn placeholder() {}' > app/ui/src/lib.rs && \
echo 'pub fn placeholder() {}' > app/client-api/src/lib.rs && \
echo 'pub fn placeholder() {}' > crates/rust-agent/src/lib.rs && \
echo 'pub fn placeholder() {}' > crates/i18n/src/lib.rs
# dx 0.7.9 performs unfiltered cargo metadata before its platform-specific
# build, so fetch the complete lockfile of the already-pruned Web workspace.
# Keep Cargo's registry/git data in this layer so a remote layer-cache hit never
# skips the fetch while leaving the later offline build with empty cache mounts.
RUN cargo fetch --locked
# ── Copy real source code ──
COPY app/web/src ./app/web/src
COPY app/web/assets ./app/web/assets
COPY app/ui/src ./app/ui/src
COPY app/ui/assets ./app/ui/assets
COPY crates/i18n/src ./crates/i18n/src
COPY app/client-api/src ./app/client-api/src
COPY crates/rust-agent/src ./crates/rust-agent/src
# Build the Dioxus frontend (from workspace root for correct path resolution)
WORKDIR /app
# Use locally installed tooling (wasm-opt from the `binaryen` apt package + wasm-bindgen-cli
# installed above, both on PATH) instead of downloading from GitHub at build time.
# NO_DOWNLOADS is the flag dioxus-cli 0.7.9 actually honors (see CliSettings::prefer_no_downloads);
# the previous WASM_BINDGEN_USE_LOCAL_OPT was silently ignored and dx still hit the network.
ENV NO_DOWNLOADS=1
ENV CARGO_NET_OFFLINE=true
# The target directory is a persistent BuildKit cache. Dioxus 0.7.9 can leave
# deleted or renamed assets in its previous public output, so clear only that
# disposable directory before rebuilding while retaining Cargo artifacts.
RUN --mount=type=cache,id=ains-web-target,target=/app/target,sharing=locked \
rm -rf -- /app/target/dx/web/release/web/public && \
dx build --locked --release --package web --platform web && \
mkdir -p /app/web-public && \
cp -a /app/target/dx/web/release/web/public/. /app/web-public/
# ── Runtime stage - nginx static file server ──
FROM nginx:alpine AS runtime
# Install curl for health checks
RUN apk add --no-cache curl
# Copy the frontend assets preserved outside the BuildKit target cache mount.
COPY --from=builder /app/web-public /usr/share/nginx/html
# Dioxus fingerprints assets referenced by the application, while browsers may
# request /favicon.ico before the WASM application injects its <link> element.
# Keep an unversioned root copy for that conventional request.
COPY app/web/assets/favicon.ico /usr/share/nginx/html/favicon.ico
# Copy default nginx configuration (can be overridden via volume mount)
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]