Files
archy/docker/nostr-vpn/Dockerfile
T

99 lines
4.2 KiB
Docker
Raw Normal View History

# syntax=docker/dockerfile:1.7
#
# Packages nostr-vpn (github.com/mmalmi/nostr-vpn) as the paid-exit seller
# daemon + its web control panel. Both apps/nostr-vpn and apps/nostr-vpn-web
# build from this one image (same binaries, different entrypoint/command),
# mirroring upstream's own umbrel/docker-compose.yml, which runs `daemon`
# and `web` as two containers sharing one /data volume with no network link
# between them — reviewed directly, not assumed.
#
# This is upstream's own umbrel/Dockerfile, unchanged except for how the
# source arrives (a pinned commit tarball here, instead of a local checkout
# in their build context) — see docs/nostr-vpn-integration-plan.md for why
# the pin exists and what was verified against this exact commit.
ARG NVPN_COMMIT=87f19447741998ab5a06aadc701abc7ae021004b
FROM debian:bookworm-slim AS source
ARG NVPN_COMMIT
# git clone, not a codeload.github.com/archive/<sha>.tar.gz tarball: the
# latter 404s from this environment even for refs/heads/main HEAD (network
# policy on that specific endpoint, not a real upstream 404 — plain
# `git clone https://github.com/...` works fine).
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
# GitHub's anonymous smart-HTTP upload-pack refuses to fetch an arbitrary
# SHA directly (only advertised refs) — fetch main by name and verify the
# pinned commit is actually what we land on, so a force-push to main can't
# silently swap out the reviewed code.
RUN git init -q . \
&& git remote add origin https://github.com/mmalmi/nostr-vpn.git \
&& git fetch -q --depth 1 origin master \
&& git checkout -q FETCH_HEAD \
&& test "$(git rev-parse HEAD)" = "${NVPN_COMMIT}" \
&& rm -rf .git
FROM node:24-bookworm AS web-builder
WORKDIR /work/web/control-panel
COPY --from=source /src/web/control-panel/package.json /src/web/control-panel/pnpm-lock.yaml ./
RUN --mount=type=cache,id=nostr-vpn-pnpm-store,target=/pnpm/store \
corepack enable \
&& corepack prepare pnpm@10.28.2 --activate \
&& pnpm install --frozen-lockfile --store-dir /pnpm/store
COPY --from=source /src/web/control-panel ./
RUN pnpm run build
FROM rust:1.94-bookworm AS rust-builder
ARG TARGETPLATFORM
WORKDIR /work
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
clang \
libclang-dev \
libdbus-1-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
COPY --from=source /src/Cargo.toml /src/Cargo.lock ./
COPY --from=source /src/crates ./crates
COPY --from=source /src/vendor ./vendor
RUN --mount=type=cache,id=nostr-vpn-cargo-registry-${TARGETPLATFORM},target=/usr/local/cargo/registry \
--mount=type=cache,id=nostr-vpn-cargo-git-${TARGETPLATFORM},target=/usr/local/cargo/git \
--mount=type=cache,id=nostr-vpn-cargo-target-${TARGETPLATFORM},target=/work/target \
cargo build --release -p nvpn -p nostr-vpn-web \
&& mkdir -p /out \
&& cp /work/target/release/nvpn /out/nvpn \
&& cp /work/target/release/nostr-vpn-web /out/nvpn-web
FROM debian:bookworm-slim AS runtime
LABEL org.opencontainers.image.source="https://github.com/mmalmi/nostr-vpn" \
org.opencontainers.image.description="nostr-vpn, packaged as an Archipelago paid-exit seller app" \
org.opencontainers.image.licenses="MIT"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
iproute2 \
iptables \
iputils-ping \
libdbus-1-3 \
procps \
wireguard-tools \
&& rm -rf /var/lib/apt/lists/*
COPY --from=rust-builder /out/nvpn /usr/local/bin/nvpn
COPY --from=rust-builder /out/nvpn-web /usr/local/bin/nvpn-web
COPY --from=web-builder /work/web/control-panel/dist /usr/share/nostr-vpn/web
COPY docker-entrypoint.sh /usr/local/bin/archy-nvpn-entrypoint.sh
RUN chmod +x /usr/local/bin/archy-nvpn-entrypoint.sh
ENV HOME=/data/home \
XDG_CONFIG_HOME=/data/config \
NVPN_CLI_PATH=/usr/local/bin/nvpn \
RUST_LOG=info
EXPOSE 38080
VOLUME ["/data"]
# No image-level ENTRYPOINT/CMD: apps/nostr-vpn and apps/nostr-vpn-web set
# their own entrypoint/custom_args in their manifests (daemon vs. web),
# both pointing at archy-nvpn-entrypoint.sh — see that script for why the
# seed-config step has to run before either binary starts.