########## 建置階段:編譯 release 二進位 ########## # edition 2024 需 Rust 1.85+;跟隨本機驗證過的 1.98 # 基礎映像可用 --build-arg 覆寫(例如網路受限時改用可達的 registry 代理) ARG RUST_IMAGE=rust:1.98-slim ARG DEBIAN_IMAGE=debian:trixie-slim FROM ${RUST_IMAGE} AS builder # rusqlite(bundled)編譯內嵌 SQLite 需要 C 編譯器 RUN apt-get update \ && apt-get install -y --no-install-recommends build-essential \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # askama 在「編譯期」讀取 templates/,因此模板目錄必須一併複製 COPY Cargo.toml Cargo.lock ./ COPY src ./src COPY templates ./templates # BuildKit 快取掛載保留 cargo registry 與 target 目錄,重複建置只重編改動部分 RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/app/target \ cargo build --release --locked \ && cp target/release/alterdb /usr/local/bin/alterdb ########## 執行階段:僅含二進位與執行期依賴 ########## # 與建置階段同基礎發行版(trixie),glibc 一致;模板已編入二進位,無需其他檔案 FROM ${DEBIAN_IMAGE} AS runtime # ca-certificates 供未來對外連線使用;建立非 root 執行帳戶(不加 shell 設定檔進 /data) RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* \ && useradd --system --no-create-home --home-dir /data appuser \ && mkdir -p /data && chown appuser:appuser /data # SQLite 數據檔集中於 /data,掛載 volume 即可持久化 VOLUME /data # 容器內必須綁 0.0.0.0 才能從宿主機存取(main.rs 讀取 ALTERDB_BIND) ENV ALTERDB_BIND=0.0.0.0:8080 \ ALTERDB_DB_PATH=/data/alterdb.db \ RUST_LOG=info USER appuser WORKDIR /data COPY --from=builder /usr/local/bin/alterdb /usr/local/bin/alterdb EXPOSE 8080 # debian-slim 無 curl/wget,以 bash 內建 /dev/tcp 探測健康端點 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD bash -c 'exec 3<>/dev/tcp/127.0.0.1/8080 \ && printf "GET /api/health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" >&3 \ && grep -q "200 OK" <&3' || exit 1 ENTRYPOINT ["/usr/local/bin/alterdb"]