chat-store/Dockerfile
kaichao b5536bf584
feat: publish accounts and key bundles via logos delivery (#7)
* feat: publish via logos delivery

* feat: protobuf definition for publish records

* feat: docker build for logos delivery deps

* feat: refactor modules splition

* chore: update docker file for exposed port
2026-07-28 19:37:56 +08:00

80 lines
3.3 KiB
Docker

# syntax=docker/dockerfile:1
########################################
# Build stage
########################################
# Nix, not the `rust` image: the binary links the native liblogosdelivery, which
# only nix builds. That library comes from nixpkgs' glibc (2.40), newer than
# bookworm's, so cargo has to run against the same nixpkgs — mixing the two
# libcs in one process does not work. Everything below therefore builds inside
# the flake's dev shell.
FROM nixos/nix:2.32.0 AS builder
# `filter-syscalls` off because the seccomp filter fails inside an emulated
# (qemu) container, which is how this image gets built on arm64 hosts.
RUN printf 'experimental-features = nix-command flakes\nfilter-syscalls = false\n' \
>> /etc/nix/nix.conf
WORKDIR /src
# The native library first and on its own layer: it is by far the slowest part
# of the build and only changes when the flake pins do.
COPY flake.nix flake.lock ./
RUN nix --accept-flake-config build .#logos-delivery --no-link
# Then the Rust dependency graph, against a stub binary, so the (also slow)
# dependency compile is cached and only re-runs when Cargo.toml/Cargo.lock change.
COPY Cargo.toml Cargo.lock ./
RUN mkdir src \
&& echo "fn main() {}" > src/main.rs \
&& nix --accept-flake-config develop --command cargo build --release --locked \
&& rm -rf src target/release/deps/chat_store* target/release/chat-store
# Now the real binary; dependency artifacts above are reused. `migrations/` is
# needed at build time too — `sqlx::migrate!()` embeds the .sql files.
COPY src ./src
COPY migrations ./migrations
RUN nix --accept-flake-config develop --command \
cargo build --release --locked --bin chat-store
# Collect what the binary loads at runtime. logos-delivery's build.rs stamps
# liblogosdelivery with an absolute store path as its soname, so the binary
# names it — along with its ELF interpreter and rpath — by absolute /nix/store
# path. Seeding the closure from those three is all the runtime image needs.
RUN nix --accept-flake-config develop --command sh -c '\
bin=target/release/chat-store; \
{ patchelf --print-needed "$bin"; \
patchelf --print-interpreter "$bin"; \
patchelf --print-rpath "$bin" | tr ":" "\n"; } \
| grep "^/nix/store/" \
| sed "s|\(/nix/store/[^/]*\).*|\1|" | sort -u \
| xargs nix-store --query --requisites | sort -u > /closure.txt' \
&& mkdir -p /output/nix/store \
&& cp target/release/chat-store /output/chat-store \
&& cp -a $(cat /closure.txt) /output/nix/store/
########################################
# Runtime stage
########################################
FROM debian:bookworm-slim AS runtime
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# The nix closure the binary resolves by absolute path, then the binary itself.
COPY --from=builder /output/nix/store /nix/store
COPY --from=builder /output/chat-store /usr/local/bin/chat-store
# Matches the default --bind 0.0.0.0:8080.
EXPOSE 8080
EXPOSE 60000/tcp
EXPOSE 60000/udp
# Persist the SQLite database on a volume rather than the container layer.
VOLUME ["/data"]
ENV RUST_LOG=info
ENTRYPOINT ["chat-store"]
CMD ["--bind", "0.0.0.0:8080", "--db", "/data/chat-store.db", "--p2p-port", "60000"]