feat(docker): use cargo-zigbuild for native cross-compilation

- Switch sqlx, reqwest, tiberius from native-tls to rustls to eliminate
  OpenSSL dependency, enabling clean cross-compilation
- Use cargo-zigbuild to cross-compile dbx-web for both amd64 and arm64
  natively without QEMU emulation for Rust compilation
- Frontend and backend stages use --platform=$BUILDPLATFORM to avoid
  emulation during build
- Remove libssl3 from runtime image (no longer needed with rustls)
This commit is contained in:
t8y2 2026-05-05 21:02:41 +08:00
parent e0cd2e88a6
commit 2ac29879e4
3 changed files with 144 additions and 42 deletions

148
Cargo.lock generated
View File

@ -1572,7 +1572,7 @@ dependencies = [
"reqwest 0.12.28",
"russh",
"rust_decimal",
"rustls",
"rustls 0.23.40",
"serde",
"serde_json",
"sqlx",
@ -1609,7 +1609,7 @@ dependencies = [
"reqwest 0.12.28",
"russh",
"rust_decimal",
"rustls",
"rustls 0.23.40",
"serde",
"serde_json",
"sqlx",
@ -1629,7 +1629,7 @@ dependencies = [
"futures",
"hex",
"log",
"rustls",
"rustls 0.23.40",
"serde",
"serde_json",
"sha2 0.10.9",
@ -3044,9 +3044,9 @@ dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"rustls 0.23.40",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tower-service",
"webpki-roots 1.0.7",
]
@ -4008,7 +4008,7 @@ dependencies = [
"percent-encoding",
"rand 0.9.4",
"rustc_version_runtime",
"rustls",
"rustls 0.23.40",
"rustversion",
"serde",
"serde_bytes",
@ -4021,7 +4021,7 @@ dependencies = [
"take_mut",
"thiserror 2.0.18",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tokio-util",
"typed-builder",
"uuid",
@ -4087,10 +4087,10 @@ dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-probe 0.2.1",
"openssl-sys",
"schannel",
"security-framework",
"security-framework 3.7.0",
"security-framework-sys",
"tempfile",
]
@ -4510,6 +4510,12 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-probe"
version = "0.2.1"
@ -4553,8 +4559,8 @@ dependencies = [
"pbkdf2 0.12.2",
"pkcs8 0.10.2",
"rand 0.8.6",
"rustls",
"rustls-pemfile",
"rustls 0.23.40",
"rustls-pemfile 2.2.0",
"rustls-pki-types",
"serde",
"serde_json",
@ -4562,7 +4568,7 @@ dependencies = [
"sha2 0.10.9",
"thiserror 1.0.69",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tracing",
"webpki-roots 0.26.11",
]
@ -5226,7 +5232,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"rustls 0.23.40",
"socket2",
"thiserror 2.0.18",
"tokio",
@ -5246,7 +5252,7 @@ dependencies = [
"rand 0.9.4",
"ring",
"rustc-hash",
"rustls",
"rustls 0.23.40",
"rustls-pki-types",
"slab",
"thiserror 2.0.18",
@ -5433,13 +5439,13 @@ dependencies = [
"num-bigint",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-native-certs",
"rustls 0.23.40",
"rustls-native-certs 0.8.3",
"ryu",
"sha1_smol",
"socket2",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tokio-util",
"url",
]
@ -5558,7 +5564,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls 0.23.40",
"rustls-pki-types",
"serde",
"serde_json",
@ -5566,7 +5572,7 @@ dependencies = [
"sync_wrapper",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tokio-util",
"tower",
"tower-http",
@ -5599,14 +5605,14 @@ dependencies = [
"log",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls 0.23.40",
"rustls-pki-types",
"rustls-platform-verifier",
"serde",
"serde_json",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.4",
"tokio-util",
"tower",
"tower-http",
@ -5935,6 +5941,18 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "rustls"
version = "0.21.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring",
"rustls-webpki 0.101.7",
"sct",
]
[[package]]
name = "rustls"
version = "0.23.40"
@ -5946,21 +5964,42 @@ dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"rustls-webpki 0.103.13",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe 0.1.6",
"rustls-pemfile 1.0.4",
"schannel",
"security-framework 2.11.1",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [
"openssl-probe",
"openssl-probe 0.2.1",
"rustls-pki-types",
"schannel",
"security-framework",
"security-framework 3.7.0",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.7",
]
[[package]]
@ -5993,11 +6032,11 @@ dependencies = [
"jni 0.22.4",
"log",
"once_cell",
"rustls",
"rustls-native-certs",
"rustls 0.23.40",
"rustls-native-certs 0.8.3",
"rustls-platform-verifier-android",
"rustls-webpki",
"security-framework",
"rustls-webpki 0.103.13",
"security-framework 3.7.0",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
@ -6009,6 +6048,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted 0.9.0",
]
[[package]]
name = "rustls-webpki"
version = "0.103.13"
@ -6150,6 +6199,16 @@ dependencies = [
"sha2 0.11.0",
]
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted 0.9.0",
]
[[package]]
name = "seahash"
version = "4.1.0"
@ -6170,6 +6229,19 @@ dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.11.1",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework"
version = "3.7.0"
@ -6729,6 +6801,7 @@ dependencies = [
"once_cell",
"percent-encoding",
"rust_decimal",
"rustls 0.23.40",
"serde",
"serde_json",
"sha2 0.10.9",
@ -6739,6 +6812,7 @@ dependencies = [
"tracing",
"url",
"uuid",
"webpki-roots 0.26.11",
]
[[package]]
@ -7407,7 +7481,7 @@ dependencies = [
"osakit",
"percent-encoding",
"reqwest 0.13.3",
"rustls",
"rustls 0.23.40",
"semver",
"serde",
"serde_json",
@ -7616,7 +7690,11 @@ dependencies = [
"pin-project-lite",
"pretty-hex",
"rust_decimal",
"rustls-native-certs 0.6.3",
"rustls-pemfile 1.0.4",
"thiserror 1.0.69",
"tokio-rustls 0.24.1",
"tokio-util",
"tracing",
"uuid",
"winauth",
@ -7727,13 +7805,23 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls 0.21.12",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
"rustls",
"rustls 0.23.40",
"tokio",
]

View File

@ -1,5 +1,7 @@
# Stage 1: Build frontend
FROM node:20-slim AS frontend
# syntax=docker/dockerfile:1
# Stage 1: Build frontend (native, no emulation)
FROM --platform=$BUILDPLATFORM node:20-slim AS frontend
WORKDIR /app
RUN npm i -g pnpm
COPY package.json pnpm-lock.yaml ./
@ -11,26 +13,38 @@ COPY tailwind.config.* postcss.config.* ./
COPY public/ public/
RUN pnpm build
# Stage 2: Build Rust backend
FROM rust:1-bookworm AS backend
# Stage 2: Cross-compile Rust backend for both platforms (native, no emulation)
FROM --platform=$BUILDPLATFORM rust:1-bookworm AS backend
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-pip gcc-aarch64-linux-gnu gcc-x86-64-linux-gnu \
&& pip3 install --break-system-packages ziglang \
&& cargo install cargo-zigbuild \
&& rustup target add x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu \
&& rm -rf /var/lib/apt/lists/*
COPY Cargo.toml Cargo.lock ./
COPY crates/ crates/
COPY src-web/ src-web/
# Create a dummy src-tauri to satisfy workspace (not built)
RUN mkdir -p src-tauri/src && echo 'fn main() {}' > src-tauri/src/main.rs && echo 'pub fn run() {}' > src-tauri/src/lib.rs
COPY src-tauri/Cargo.toml src-tauri/
COPY src-tauri/build.rs src-tauri/
COPY src-tauri/tauri.conf.json src-tauri/
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
cargo build --release -p dbx-web && \
cp /app/target/release/dbx-web /usr/local/bin/dbx-web
cargo zigbuild --release -p dbx-web \
--target x86_64-unknown-linux-gnu \
--target aarch64-unknown-linux-gnu && \
mkdir -p /out/linux/amd64 /out/linux/arm64 && \
cp /app/target/x86_64-unknown-linux-gnu/release/dbx-web /out/linux/amd64/ && \
cp /app/target/aarch64-unknown-linux-gnu/release/dbx-web /out/linux/arm64/
# Stage 3: Final image
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
COPY --from=backend /usr/local/bin/dbx-web /usr/local/bin/
ARG TARGETPLATFORM
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=backend /out/${TARGETPLATFORM}/dbx-web /usr/local/bin/
COPY --from=frontend /app/dist /app/static
ENV DBX_STATIC_DIR=/app/static
ENV DBX_DATA_DIR=/app/data

View File

@ -14,12 +14,12 @@ chrono = { version = "0.4", features = ["serde"] }
rust_decimal = { version = "1", features = ["serde"] }
anyhow = "1"
uuid = { version = "1", features = ["v4", "serde"] }
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-native-tls", "mysql", "postgres", "sqlite", "json", "chrono", "uuid", "rust_decimal"] }
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "mysql", "postgres", "sqlite", "json", "chrono", "uuid", "rust_decimal"] }
redis = { version = "0.32.2", features = ["tokio-comp", "tls-rustls", "tokio-rustls-comp"] }
rustls = { version = "0.23", features = ["aws-lc-rs"] }
duckdb = { version = "1.3.2", features = ["bundled"] }
tiberius = { version = "0.12.3", features = ["tds73", "chrono", "rust_decimal"] }
reqwest = { version = "0.12", features = ["json", "stream"] }
tiberius = { version = "0.12.3", default-features = false, features = ["tds73", "chrono", "rust_decimal", "rustls"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] }
futures = "0.3"
mongodb = "3.2.5"
oracle-rs = "0.1"