mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-19 02:20:02 -05:00
See CHANGELOG.md (6.0.0). Full history of the work: tag ftx2-last and branch history archived in ps5upload-docs.
105 lines
5.7 KiB
Docker
105 lines
5.7 KiB
Docker
# Minimal scratch image for ps5upload-engine. Build context is the REPO ROOT
|
|
# (the build COPYs payload/ and third_party/), NOT engine/.
|
|
# Official multi-arch image: docker pull ghcr.io/phantomptr/ps5upload-engine:latest
|
|
# docker build -f engine/Dockerfile -t ps5upload-engine .
|
|
# On a Linux server, use engine/compose.yaml, or the equivalent:
|
|
# docker run -d --network host -v ps5upload-data:/data \
|
|
# -e PS5_ADDR=192.168.1.50 -e PS5UPLOAD_ALLOW_IP=192.168.1.0/24 \
|
|
# ghcr.io/phantomptr/ps5upload-engine
|
|
# Without PS5UPLOAD_ALLOW_IP every request from another machine gets a 403
|
|
# that names the address it refused.
|
|
# Env: PS5UPLOAD_ENGINE_PORT (19113), PS5_ADDR (192.168.137.2),
|
|
# PS5UPLOAD_ALLOW_IP (comma-separated IPs or CIDR ranges allowed past the
|
|
# loopback guard),
|
|
# PS5UPLOAD_PKG_HOST_IP (host LAN IP the PS5 fetches pkg bytes from during a
|
|
# stream install — REQUIRED on Docker Desktop macOS/Windows, where the
|
|
# container's own routing guess is a NAT address the PS5 can't reach back),
|
|
# PS5UPLOAD_PAYLOAD_DIR (directory holding ps5upload.elf +
|
|
# ps5upload-installer.elf, overriding the images built into this binary —
|
|
# only needed if you built the image without them).
|
|
#
|
|
# IMPORTANT for Docker Desktop (macOS/Windows): the engine's loopback guard
|
|
# rejects requests that don't come from 127.0.0.1/::1. Docker's port-forwarding
|
|
# NATs connections through the VM bridge, so the container sees a bridge IP
|
|
# (e.g. 172.17.0.1), NOT loopback — and all requests get 403 "loopback only".
|
|
# Two workarounds:
|
|
# 1. Set PS5UPLOAD_ALLOW_IP to the Docker bridge gateway IP:
|
|
# docker run --rm -p 19113:19113 \
|
|
# -e PS5_ADDR=192.168.1.50 \
|
|
# -e PS5UPLOAD_ALLOW_IP=172.17.0.1 \
|
|
# ps5upload-engine
|
|
# 2. On Linux hosts, use --network host (connections are true loopback):
|
|
# docker run --rm --network host \
|
|
# -e PS5_ADDR=192.168.1.50 \
|
|
# ps5upload-engine
|
|
# Note: on macOS/Windows Docker Desktop, --network host does NOT work (the
|
|
# daemon runs in a VM and can't bind to the host's LAN). Use option 1 and
|
|
# note that the PS5 must be reachable from the Docker VM's network (may
|
|
# require additional routing/bridging for the VM to reach the LAN).
|
|
#
|
|
# SECURITY: the /api/* surface is UNAUTHENTICATED — it can install/uninstall
|
|
# titles and read/write/delete files on the PS5. By default only loopback may
|
|
# reach it. PS5UPLOAD_ALLOW_IP opens it to the listed IP(s) so a remote desktop
|
|
# client can drive a self-hosted engine. An IP allowlist is spoofable and grants
|
|
# any process on those hosts full control, so set it ONLY on a trusted LAN and
|
|
# NEVER publish this container to an untrusted network or the internet. Bind it
|
|
# to the LAN interface (e.g. `-p 192.168.1.10:19113:19113`), not 0.0.0.0 on a
|
|
# public host.
|
|
|
|
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
|
|
|
|
# Built from the REPO ROOT, not engine/, because the workspace patches
|
|
# `unrar` to the vendored copy at third_party/unrar (see that directory's
|
|
# README). A build context of engine/ puts that path outside the context
|
|
# and cargo fails with "unable to update /third_party/unrar".
|
|
WORKDIR /build
|
|
COPY engine engine
|
|
COPY third_party third_party
|
|
# The PS5 helper ELFs the engine embeds (build.rs looks for them at
|
|
# <repo root>/payload). Without this the image builds fine but installs
|
|
# UPDATES and DLC with no installer to send — the exact #152 failure —
|
|
# because `have_bundled_dpi` is never set. ps5upload-installer.elf is committed,
|
|
# so this always works; ps5upload.elf appears only if you ran
|
|
# `make payload` first (it needs the PS5 payload SDK).
|
|
COPY payload payload
|
|
WORKDIR /build/engine
|
|
RUN cargo build --release -p ps5upload-engine
|
|
|
|
# The runtime image is `scratch`, which has no /tmp and no home: the engine
|
|
# could not stage an uploaded package ("could not create upload dir:
|
|
# Permission denied"), cache artwork, or remember saved servers and install
|
|
# history. Make both here (scratch has no mkdir) and copy them across below.
|
|
# /data is world-writable too (sticky, like /tmp) so a `user:` override in
|
|
# Compose — common on NAS boxes, e.g. `user: "1000:1000"` (#346) — can still
|
|
# write its state there; its owner is the default runtime user.
|
|
RUN mkdir -p /rootfs/tmp /rootfs-data/data && chmod 1777 /rootfs/tmp /rootfs-data/data
|
|
|
|
FROM scratch
|
|
COPY --from=builder /build/engine/target/release/ps5upload-engine /ps5upload-engine
|
|
# /tmp: staging for uploaded packages, archive extraction and the like. It
|
|
# is copied as a child of /rootfs because copying a directory applies only
|
|
# its contents: `COPY /rootfs/tmp /tmp` left a 0755 root-owned /tmp and the
|
|
# upload still failed. /data: the engine's home (HOME=/data puts its state in
|
|
# /data/.ps5upload), owned by the runtime user so it is writable.
|
|
COPY --from=builder /rootfs/ /
|
|
COPY --from=builder --chown=65532:65532 /rootfs-data/ /
|
|
ENV HOME=/data TMPDIR=/tmp
|
|
# Saved servers (with their encrypted credentials), install history, the
|
|
# artwork cache and the backport library live here. Mount a volume on it so
|
|
# they survive a container upgrade: `-v ps5upload-data:/data`.
|
|
VOLUME ["/data"]
|
|
EXPOSE 19113
|
|
# Run as an unprivileged user (65532 = nobody in distroless convention).
|
|
# scratch has no /etc/passwd, so we use a raw numeric UID — the kernel
|
|
# doesn't need a passwd entry to run a process. Port 19113 > 1024 so
|
|
# no CAP_NET_BIND_SERVICE needed.
|
|
USER 65532:65532
|
|
# scratch has no shell or HTTP client, so the engine probes itself:
|
|
# `--healthcheck` exits 0 when GET /api/jobs answers 200 (no PS5 needed).
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD ["/ps5upload-engine", "--healthcheck"]
|
|
ENTRYPOINT ["/ps5upload-engine"]
|