Docker Hub rebuilt node:22-alpine on 2026-09-17 with the same Node
(22.23.2) but refreshed Alpine layers. That rebuild dies under QEMU while
cross-building the arm64 leg: `qemu: uncaught target signal 4 (Illegal
instruction)`, exit 132, during `pnpm install`.
Three consecutive release builds failed identically on it. Every other
input was unchanged and verified by digest — runner image 20260907.300.1,
tonistiigi/binfmt sha256:400a4873, pnpm pinned at 11.5.2, lockfile
untouched — and quality-checks, which runs natively, passed every time.
The tag was the only floating input:
last green build 09-15 node:22-alpine@sha256:c610fcdf built 2026-07-29
failing 09-20 node:22-alpine@sha256:b6f26b36 built 2026-09-17
Pinned to the older of the two. It ships nothing: the builder stage is
discarded and only ui/dist is copied out, so no Alpine bytes reach the
runtime image and holding an older base costs no exposure.
This is a stopgap for the emulated build, not a fix for it. The durable
answer is building the arm64 leg on a native runner, which removes the
whole failure class.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Addresses a full-project review. Backend correctness and availability:
- ytdl: cancel() only SIGKILLs the child's process group when the child
actually became its own group leader, so a race (or failed setpgrp)
can no longer kill the whole server; kill the group on cancel and on
shutdown to avoid orphaned ffmpeg children
- ytdl: dedicated ThreadPoolExecutor for download supervision so active
downloads can't starve extract_info / live probes on the default pool
- ytdl/main/subscriptions: route fire-and-forget tasks through a
bg_tasks helper that keeps a strong ref and logs failures
- subscriptions: run flat-playlist extraction in an executor and check
feeds with bounded concurrency so one slow feed can't block the loop;
set last_checked on failure so broken feeds aren't retried every 60s
- main: validate ids on /start & /delete and numeric env vars at startup;
return 400 (not 500) on bad subscriptions/update input; serve /history
from memory; move get_custom_dirs off the event loop; restrict t=
stripping to YouTube hosts; drop double percent-decode in state guard
- dl_formats/ytdl: enforce requested caption format via
FFmpegSubtitlesConvertor and strip VTT header metadata only in the
pre-cue region so real dialogue is preserved
- ytdl: throttle progress events, dedup adds against pending, clear
filename/size on error and reject out-of-dir trashcan deletes, pin
fork start-method on Linux only
Frontend:
- retry deletes the done record only after a successful re-add
- surface HTTP errors for delete/start and reset the deleting flag
- ignore late 'updated' events for rows no longer in the queue
- track table rows by map key; FileSizePipe uses base-1024
Also: HTTPS-aware Docker healthcheck, dead-code removal, and shared
helpers for path-containment and yt-dlp option merging. Adds/updates
unit tests throughout (250 backend tests passing).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
```
Step 7/21 : COPY Pipfile* docker-entrypoint.sh .
When using COPY with more than one source file, the destination must be a directory and end with a /
```
why.....
- Added support for yt-dlp emp path
- Formatted with Black
- Updated README to reflect new TEMP_DIR setting; linted
- Modified Dockerfile to strip carriage return characters from docker-entrypoint.sh script to fix building the image on Windows
- Added example docker-compose.yml config