Files
ps5upload/engine/Dockerfile.webui
T
PhantomPtrandClaude Opus 5.5 832e2afcd2 fix(docker): the web UI image bundles the FAQ and Changelog (#337)
* fix(docker): the web UI image bundles the FAQ and Changelog

Since the FAQ and Changelog screens bundle ../FAQ.md and ../CHANGELOG.md,
the web UI image's frontend stage failed: it built the client at /src
and .dockerignore excluded every *.md. The stage now keeps the repo
layout (/repo/client) and copies the two files in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(scripts): the audit counts a script's node:test file as used

scripts:check runs every *.test.mjs by pattern, so the test beside
stale-client-lib.mjs is named nowhere and the strict audit called it an
orphan (repo scripts failed on all three OSes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:04:23 -07:00

85 lines
3.9 KiB
Docker

# Full-stack web UI image for ps5upload-engine.
# Serves the complete React frontend at http://<host>:19113 so any browser
# on an allowlisted IP can manage a PS5 — no native client required.
#
# Build (from the repo root, NOT engine/):
# docker build -f engine/Dockerfile.webui -t ps5upload-engine-webui .
#
# Run:
# docker run --rm -p 19113:19113 \
# -e PS5_ADDR=192.168.1.50:9113 \
# -e PS5UPLOAD_ALLOW_IP=192.168.1.20 \
# ps5upload-engine-webui
#
# Then open http://192.168.1.<host>:19113 in a browser on the machine whose
# IP you set in PS5UPLOAD_ALLOW_IP.
#
# DOCKER DESKTOP (macOS/Windows): the engine's loopback guard rejects
# connections from Docker's NAT bridge. You MUST set PS5UPLOAD_ALLOW_IP to
# the bridge gateway (usually 172.17.0.1) for port-forwarded connections to
# work. On Linux, prefer --network host instead. See engine/Dockerfile for
# full networking details. Note: on macOS/Windows the Docker VM is NAT'd
# and may not be able to reach the PS5 on your LAN — this is a Docker
# Desktop limitation, not an engine bug.
#
# The image also carries the two PS5 helper ELFs (ps5upload.elf and the DPI
# install daemon). The browser cannot open a socket to the console's loader
# or hold those bytes itself, so without them the web UI can install base
# games but not updates or DLC — the web UI half of #152. Override with
# PS5UPLOAD_PAYLOAD_DIR if you need to pin different ones.
#
# SECURITY: the web UI is UNAUTHENTICATED. Anyone whose IP is in
# PS5UPLOAD_ALLOW_IP gets full control over your PS5. Only add IPs from
# your own trusted LAN. Never expose port 19113 to the internet.
# ── Stage 1: build the React frontend ────────────────────────────────────────
FROM node:26-alpine AS frontend
# The client at its repo-relative place: the FAQ and Changelog screens bundle
# ../FAQ.md and ../CHANGELOG.md from the repo root.
WORKDIR /repo/client
# Copy only the client package files first so npm ci is cached
COPY client/package.json client/package-lock.json ./
RUN npm ci --silent
# Now copy the rest of the client source and build
COPY client/ .
COPY FAQ.md CHANGELOG.md ../
RUN npm run build:vite
# ── Stage 2: build the Rust engine with embedded web UI ──────────────────────
FROM rust:alpine AS builder
# g++ compiles unrar's bundled C++ against musl; musl target links static.
RUN apk add --no-cache musl-dev g++ make
# Keep engine/ and third_party/ at their real repo-relative positions
# rather than flattening engine/ into /build: the workspace patches
# `unrar` to ../third_party/unrar (see third_party/unrar/README.md), and
# flattening puts that path outside the image entirely.
WORKDIR /build
COPY engine/ ./engine/
COPY third_party/ ./third_party/
# See engine/Dockerfile: build.rs embeds these, and the web UI's update /
# DLC install is exactly what breaks without them (the web UI half of #152).
COPY payload/ ./payload/
WORKDIR /build/engine
# Populate the webui/ embed directory from the frontend build output.
# rust-embed will bake every file in this directory into the binary.
COPY --from=frontend /repo/client/dist/ ./crates/ps5upload-engine/webui/
RUN cargo build --release -p ps5upload-engine --features webui
# ── Stage 3: minimal scratch image ───────────────────────────────────────────
FROM scratch
COPY --from=builder /build/engine/target/release/ps5upload-engine /ps5upload-engine
EXPOSE 19113
# Run as an unprivileged user (65532 = nobody in distroless convention).
# See engine/Dockerfile for rationale on numeric UID in scratch.
USER 65532:65532
# Health: GET /api/jobs returns 200 once the HTTP server is live (no PS5
# contact needed). scratch has no shell/wget, so no in-image HEALTHCHECK;
# use an external probe (see engine/Dockerfile).
ENTRYPOINT ["/ps5upload-engine"]