# syntax=docker/dockerfile:1
#
# Build strategy: BuildKit cache mounts instead of cargo-chef.
#
# The cargo registry and the `target/` directory are persisted in BuildKit
# cache mounts, so a release build only recompiles the `fig` crate itself —
# all 340+ dependency artifacts are reused from the previous build. That makes
# cargo-chef (and the `cargo install cargo-chef` + full `chef cook` passes it
# needs) redundant on a machine with a persistent BuildKit cache, which is how
# `mise run release` builds.
#
# Note: cache mounts are local to the BuildKit daemon. A cold machine (fresh
# CI runner) pays one full dependency build; every build after that is warm.
FROM rust:slim-bookworm AS builder
WORKDIR /app
# mold links the final binary several times faster than GNU ld.
# gcc 12 (bookworm) drives it via -fuse-ld=mold, so no clang needed.
# No pkg-config/libssl-dev: git2 is built with default-features off and
# vendors libgit2, and nothing in the tree links OpenSSL.
RUN apt-get update \
&& apt-get install -y --no-install-recommends mold \
&& rm -rf /var/lib/apt/lists/*
ENV RUSTFLAGS="-C link-arg=-fuse-ld=mold" \
CARGO_INCREMENTAL=0 \
CARGO_NET_RETRY=10 \
CARGO_TERM_COLOR=always
COPY Cargo.toml Cargo.lock ./
COPY assets ./assets
COPY plugin ./plugin
COPY src ./src
COPY dist ./dist
# `mac/src-tauri` is a workspace member but is dockerignored, so
# members must be set to only ["."] or cargo refuses to load the workspace.
RUN sed -i 's/members = \[.*\]/members = ["."]/g' Cargo.toml
# `target/` lives in the cache mount and is therefore not part of the layer —
# the binary has to be copied out before the mount is unmounted.
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,target=/app/target,sharing=locked \
cargo build --release \
&& cp target/release/notify /usr/local/bin/notify
# Runtime stage
FROM debian:bookworm-slim
LABEL remote="silenloc/notify"
WORKDIR /app
# ca-certificates: turso sync talks HTTPS through rustls, which can be
# configured to read system roots. No git/openssl in the runtime: the tree has
# no git2 dependency, and vendored libgit2 (if reintroduced) brings its own TLS.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local/bin/notify /app/notify
COPY --from=builder /app/dist /app/dist
ENV NOTIFY_DIST_DIR=/app/dist
# DB state lives on a volume, not in a layer: it must survive container
# replacement. `DB_PATH` is relocated to /app/data so the volume only holds
# mutable state, never the binary.
# Point a named volume at /app/data to keep data across upgrades.
ENV DB_PATH=/app/data/notify.db
RUN mkdir -p /app/data \
&& chmod 755 /app/data
VOLUME ["/app/data"]
# Default PORT is 8080 (see src/config.rs); override with `-e PORT=...`
EXPOSE 8080
# Run the binary
ENTRYPOINT ["./notify"]