web/build.mjs builds a static site, web/dist, with the icons and typeface beside the pages; Dockerfile.web serves it with Caddy, which passes /api and /media to ipx on the same origin, so cookies, live updates and Cloudflare Access work as before. ipx serves no page any more: build.rs and every include_str! of the web files are gone, and its image is built without node. What ipx did to the page as it served it is kept another way. Caddy asks ipx before serving a page (forward_auth): /api/page-check sends a browser not signed in to /login and a non-admin away from /admin, and refuses them /admin.js; /api/login-check sends someone Access vouches for past the form; a page asked for with ?token= goes to /api/signin, which sets the cookie. The theme and the admin link, once written into the page per person, are set by web/boot.js in <head> from the theme cookie and the last visit, before the first frame, and /api/me brings the version and the account's theme from before. Caddy strips the Cf-Access-* headers from every peer but TUNNEL_PEER, the address cloudflared's requests come from, which is the boundary trusted_proxies drew; ipx then trusts only Caddy's address. The browser suite runs Caddy in front of its daemon, so it tests what production would run. Not deployed: production's cutover is on #203. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
2.0 KiB
Docker
48 lines
2.0 KiB
Docker
# Build. rusqlite is bundled (compiles SQLite from source) and librqbit needs a C
|
|
# toolchain, so the builder needs cc. TLS is rustls throughout, so no OpenSSL headers.
|
|
# The pages are ipx-web's (Dockerfile.web), so no node here (#203).
|
|
FROM rust:1-slim-trixie AS build
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
WORKDIR /src
|
|
|
|
# Dependencies first, so editing the source does not rebuild librqbit every time: each crate of
|
|
# the workspace as an empty stub, its manifest real.
|
|
COPY Cargo.toml Cargo.lock ./
|
|
COPY crates/ipx/Cargo.toml crates/ipx/
|
|
COPY crates/feed/Cargo.toml crates/feed/
|
|
COPY crates/directory/Cargo.toml crates/directory/
|
|
RUN mkdir -p crates/ipx/src crates/feed/src crates/directory/src \
|
|
&& echo 'fn main(){}' > crates/ipx/src/main.rs && touch crates/feed/src/lib.rs \
|
|
&& echo 'fn main(){}' > crates/directory/src/main.rs && touch crates/directory/src/lib.rs \
|
|
&& cargo build --release --locked -p ipx \
|
|
&& rm -rf crates/ipx/src crates/feed/src crates/directory/src
|
|
|
|
COPY crates ./crates
|
|
# cargo skips a rebuild if mtimes look untouched; make sure it does not.
|
|
RUN touch crates/ipx/src/main.rs crates/feed/src/lib.rs && cargo build --release --locked -p ipx
|
|
|
|
FROM debian:trixie-slim
|
|
# ffmpeg is DeadAir's (#171): it finds the silences and copies the frames kept. Debian's adds
|
|
# about 480 MB, once: the layer stays cached until the base image changes.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates gosu ffmpeg \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
COPY --from=build /src/target/release/ipx /usr/local/bin/ipx
|
|
COPY docker-entrypoint.sh /usr/local/bin/
|
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|
|
|
ENV IPX_CONFIG=/config/config.toml \
|
|
IPX_DATA_DIR=/data \
|
|
IPX_LOG=ipx=info \
|
|
PUID=99 \
|
|
PGID=100
|
|
VOLUME ["/config", "/data", "/downloads"]
|
|
|
|
# Web UI, and the BitTorrent peer port (TCP and UDP -- DHT needs the UDP side).
|
|
EXPOSE 8099/tcp 6881/tcp 6881/udp
|
|
|
|
ENTRYPOINT ["docker-entrypoint.sh"]
|
|
CMD ["ipx", "daemon"]
|