diff --git a/Dockerfile.nas b/Dockerfile.nas index 9b562197..d64a43c7 100644 --- a/Dockerfile.nas +++ b/Dockerfile.nas @@ -1,9 +1,12 @@ -# Build the customized Plainleaf client and Rust server for an amd64 NAS. -FROM node:24.13.0-bookworm-slim AS client-builder +# Build the customized Plainleaf client and Rust server for an amd64 NAS. Build +# stages run on the builder's native architecture; only the Rust output and +# final image target amd64. This keeps Apple Silicon cross-builds practical. +FROM --platform=$BUILDPLATFORM node:24.13.0-bookworm-slim AS client-builder -RUN apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates git \ - && rm -rf /var/lib/apt/lists/* +# The build script calls `git describe` and falls back to GITHUB_SHA when it +# exits non-zero. A tiny stub avoids installing Git into this disposable stage. +RUN printf '#!/bin/sh\nexit 1\n' > /usr/local/bin/git \ + && chmod +x /usr/local/bin/git WORKDIR /src COPY . . @@ -12,31 +15,54 @@ ARG GITHUB_SHA=unknown RUN npm ci \ && npm run build -FROM rust:bookworm AS server-builder +FROM --platform=$BUILDPLATFORM rust:bookworm AS server-builder + +ENV RUSTUP_DIST_SERVER=https://rsproxy.cn \ + RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup + +RUN sed -i \ + -e 's|http://deb.debian.org/debian|http://mirrors.aliyun.com/debian|g' \ + -e 's|http://deb.debian.org/debian-security|http://mirrors.aliyun.com/debian-security|g' \ + /etc/apt/sources.list.d/debian.sources \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + gcc-x86-64-linux-gnu libc6-dev-amd64-cross \ + && rm -rf /var/lib/apt/lists/* WORKDIR /src -COPY --from=client-builder /src /src +COPY . . +COPY --from=client-builder /src/client_bundle /src/client_bundle +COPY --from=client-builder /src/version.json /src/version.json -RUN cargo build --locked --release -p silverbullet \ - && strip target/release/silverbullet +RUN rustup target add x86_64-unknown-linux-gnu + +ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \ + CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc + +RUN printf '[source.crates-io]\nreplace-with = "rsproxy"\n\n[source.rsproxy]\nregistry = "sparse+https://rsproxy.cn/index/"\n' \ + > /usr/local/cargo/config.toml + +RUN --mount=type=cache,id=plainleaf-cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=plainleaf-cargo-git,target=/usr/local/cargo/git \ + --mount=type=cache,id=plainleaf-cargo-target,target=/src/target \ + cargo build --locked --release -p silverbullet --target x86_64-unknown-linux-gnu \ + && x86_64-linux-gnu-strip target/x86_64-unknown-linux-gnu/release/silverbullet \ + && cp target/x86_64-unknown-linux-gnu/release/silverbullet /plainleaf FROM debian:bookworm-slim -RUN apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates curl git openssh-client tini \ - && rm -rf /var/lib/apt/lists/* - ENV SB_HOSTNAME=0.0.0.0 \ SB_FOLDER=/space \ SB_PORT=3000 \ SB_NAME=Plainleaf \ SB_SHELL_BACKEND=off -COPY --from=server-builder /src/target/release/silverbullet /usr/local/bin/plainleaf +COPY --from=server-builder /plainleaf /usr/local/bin/plainleaf +COPY --from=server-builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \ - CMD curl --fail "http://127.0.0.1:${SB_PORT}/.instance" || exit 1 + CMD kill -0 1 -ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/plainleaf"] +ENTRYPOINT ["/usr/local/bin/plainleaf"] CMD ["--single"] diff --git a/deploy/nas/README.md b/deploy/nas/README.md index b6ed9962..30d21a72 100644 --- a/deploy/nas/README.md +++ b/deploy/nas/README.md @@ -1,7 +1,8 @@ # Plainleaf on ZSpace NAS -This deployment builds the customized Plainleaf source on an amd64 ZSpace NAS. -It keeps deployment files and Markdown data separate: +This deployment runs an amd64 image on the ZSpace NAS. Build the image on the +development machine, then transfer and load it on the NAS; the NAS does not +need Docker Hub access. Deployment files and Markdown data remain separate: - Deployment: `个人空间/docker/plainleaf` - Markdown space: `个人空间/笔记管理/Plainleaf` @@ -13,8 +14,7 @@ deployment-local `.env` file that must not be committed. The intended `.env` keys are: ```dotenv -PLAINLEAF_GIT_SHA=94d310d71211de57339724a9ad5cb21f214e101a -PLAINLEAF_IMAGE_TAG=94d310d7 +PLAINLEAF_IMAGE_TAG= PLAINLEAF_UID=1001 PLAINLEAF_GID=1001 PLAINLEAF_PORT=3000 diff --git a/deploy/nas/compose.yaml b/deploy/nas/compose.yaml index e9e9e5e7..e6104af3 100644 --- a/deploy/nas/compose.yaml +++ b/deploy/nas/compose.yaml @@ -2,11 +2,6 @@ name: plainleaf services: plainleaf: - build: - context: ../.. - dockerfile: Dockerfile.nas - args: - GITHUB_SHA: ${PLAINLEAF_GIT_SHA:-unknown} image: plainleaf:${PLAINLEAF_IMAGE_TAG:-local} container_name: plainleaf restart: unless-stopped @@ -26,9 +21,9 @@ services: - no-new-privileges:true cap_drop: - ALL - init: false + init: true healthcheck: - test: ["CMD", "curl", "--fail", "http://127.0.0.1:3000/.instance"] + test: ["CMD-SHELL", "kill -0 1"] interval: 30s timeout: 5s start_period: 20s