Files
Frank 327e78b950 docs(vault): destroy the dead weight — 53 pages and the change diary
The vault was 155 pages / 31,210 lines, most of it measurement ledgers for
payloads that no longer run. A throughput figure for a runtime nobody operates is
not a record: AI moves faster than the vault, so the number is wrong before
anyone reads it, and a wrong number in a runbook gets believed. Per the new
purpose test in `AGENTS.md` → *Documentation Policy*, it is destroyed.

Gone (`.AGENTTRASH/20261019-destruction/`, KILL-LIST.txt is the manifest):
- the `frank-medium` endpoint and its five era pages, `frank-npu`, FastFlowLM,
  the ikllama/kingjones/dealign/frank-redo eras, the ling/swift15/freetoken/ubatch
  campaign pages, qwen3.8 spec-matrix and strix-optimizations, the two
  "Running Qwen3.6 …" pages;
- the whole `Pipeline Parallelism/` folder (no live script passes a pipeline flag)
  and the multi-device/x4-pair/hybrid/offload experiment pages;
- every vLLM page — no vLLM endpoint exists on this fleet;
- `LLM/deployment.md` (`Architecture/Deployment Flow.md` is the test-referenced
  owner) and the external surveys (SGLang, Lemonade, llama.cpp forks/diff,
  self-hosted app census, the TTS survey) that were obsolete by construction;
- `log.md`, 2,380 lines. Git holds the chronology; a causal law belongs to the
  page that owns the thing it governs, never to a diary.

Survivors: 101 pages, 17,542 lines, 0 OKF violations, 0 unresolved links. Eras
tables keep the window, payload, runtime, reason and rollback pointer; the rate
columns are blanked. The live shapes stay verbatim — those numbers are what the
deployer and `models.yml` consume.
2026-10-19 10:56:37 -07:00

8.7 KiB

type, description, tags, timestamp
type description tags timestamp
reference Copyparty is a lightweight file server and media streamer that runs as a single Python binary.
dankserver
copyparty
2026-09-03

Copyparty

Copyparty is a lightweight file server and media streamer that runs as a single Python binary. It handles large payloads, media streaming, resumable uploads, directory browsing, and WebDAV from one process.

Host: Dankserver — Access: files.franksdank.cloud guarded by the Anubis → Authentik chain (Caddy routes it post-auth to 192.168.0.235:3923); the published port itself stays unauthenticated on the LAN — Docs: https://github.com/9001/copyparty

Facts

Item Value
Running image ghcr.io/9001/copyparty-ac:latest (ac = full edition; the bare copyparty:latest tag does not exist — ghcr answers 403 on the token request for nonexistent repos). Upstream latest v1.20.24 (2026-09-19); v1.20.21 at research time (2026-08)
Port 3923 (host) → 3923 (container)
Volume bind mount the shared root directory
Auth Per-directory .cpy config files, HTTP basic auth, dirkeys, filekeys
Streaming HTTP range requests, HLS, WebDAV, WOPI (Office editing)
Docker editions dj (document + media), iv (image + video), v (video only)

Configuration

Command-line interface (ac edition)

The ac edition's entrypoint is /bin/ash /z/cpp.sh -c /z/initcfg — it parses a config file, then execs python3 -m copyparty "$@", so accounts and volumes are passed as argv flags, not env vars. COPAY_PASS/COPAY_MODE envs are not consumed by this image (zero COPAY_ references in the package). The deployed interface:

command: ["-a", "dank:${COPAY_PASS}", "-v", "/w::r:ra,dank"]

-a takes USER:PASS. -v takes src:dst:perm1:perm2:... (authoritative: python3 -m copyparty --help-accounts inside the image, v1.20.21): each perm field is <letters>[,user[,user...]] and a field with no username applies to every unauthenticated request. Letters: r read (list + download), w upload, m move, d delete, a admin (control panel, config reload), A = rwmda. (everything). Empty dst mounts at the basename of src → URL /w.

Read-only posture (2026-08-31): ::r = browse + download for anonymous (required: the guarded files.franksdank.cloud chain delivers authentik'd traffic to copyparty unauthenticated), :ra,dank = admin for the dank account. No w/m/d for anyone — uploads, moves, and deletes are rejected server-side over HTTP, PUT, and WebDAV alike. There is no dedicated "reject uploads" volflag; the perms field is the documented mechanism (--help-flags volflags only throttle/reshape uploads).

History: the pre-2026-08-31 flag -v /w::A was not "A for dank, nothing for anonymous" as an earlier revision of this page claimed — the bare A granted full read/write/delete to anyone reaching port 3923. Verified live the same day: anonymous GET /Movies/ → 200, PROPFIND / → 207, PUT → 201.

Configuration File Options

Copyparty reads its configuration from initcfg (or config in the /data directory). Key options:

  • use-bwrap: n — Disable bwrap sandboxing for ffmpeg (default in Docker). Set to y to enable.
  • shadowing //NULL — Full unmap of a volume from the filesystem.
  • Config env-var expansion: Use ${VAR} syntax in [global] section for environment variable substitution.

Docker Editions

Different editions bundle different libraries:

Edition Bundled Libraries Use Case
dj Document + image + video libraries Full-featured server
iv Image + video libraries Image and video focused
v Video only Transcoding only, minimal footprint

The iv edition is no longer available for arm32/armv6. Use dj for maximum compatibility.

Volumes

Live deployment: the whole LUKS array is served at URL /w Volume=/mnt/entropy:/w:ro in the quadlet unit (Entropy Volume) — read-only at the mount level, so no containerized consumer can write into the array through this path regardless of account permissions. The ac edition takes its volume roots from argv (-v /w::r:ra,dank), not from a /data convention; see #Command-line interface (ac edition) above.

Docker Compose (reference — retired 2026-09-01; live deployment is the quadlet unit below)

  copyparty:
    image: ghcr.io/9001/copyparty-ac:latest
    container_name: copyparty
    restart: unless-stopped
    command: ["-a", "dank:${COPAY_PASS}", "-v", "/w::r:ra,dank"]
    ports:
      - "3923:3923"
    volumes:
      - /mnt/entropy:/w
      - /opt/copyparty/cfg:/cfg
    healthcheck:
      test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3923/')"]
      interval: 30s
      timeout: 10s
      retries: 3

${COPAY_ACCOUNT}/${COPAY_PASSWORD} are never written into the unit: they live in the host-local /home/dank/Containers/copyparty/env (0600) loaded via [Service] EnvironmentFile= so systemd expands them into Exec=-a ${COPAY_ACCOUNT}:${COPAY_PASSWORD} at start. The password still lands in the container argv — visible to anyone who can run podman inspect copyparty on the host.

Deployment (Quadlet)

Since 2026-09-01: dankserver/copyparty/quadlet/copyparty.container → copyparty.service, deployed with ./scripts/deploy.sh dankserver --service copyparty. Cutover details:

  • v1 generator rejects Command= → the argv lives in Exec=.
  • No HealthCmd= — the v1 generator splits unquoted spaces in that key; self-healing is Restart=always.
  • PublishPort=3923:3923 — the first cutover dropped it (unit joined dankserver_appnet), copyparty answered inside the netns only; the published-port seam test now pins 3923 alongside 8085/8096/8083.
  • Config root moved /opt/copyparty → /home/dank/Containers/copyparty/cfg.
  • The deployer refuses to start the unit before the env file exists, so a missing seed cannot create an admin account with a garbage password.

Healthcheck

A simple HTTP check on port 3923 works. The root path returns HTTP 200 with the directory listing.

WOPI Integration

Copyparty v1.20.9+ supports WOPI (Web Application Open Platform Interface) for editing Office documents in the web UI via Collabora Online. Enable with the --wopi-accs flag to limit WOPI access to specific paths.

Security Advisories

Version Advisory CVE Issue
v1.20.19 GHSA-phv8-wgjp-g4p9 CVE-2026-104102 FTP upload outside the defined volumes (limited path traversal)
v1.20.17 GHSA-x5pq-m9p8-f4vx CVE-2026-70657 dirkey/filekey confusion
v1.20.9 GHSA-62cr-6wp5-q43h CVE-2026-27948 reflected XSS via the ?setck= URL parameter (not the upload path — the separate upload/DOM-XSS advisory is GHSA-m2jw-cj8v-937r)

Upgrade to v1.20.19+ to cover all known advisories. The dirkey fix (v1.20.17) matters if using both dirkeys and filekeys. Each row's patched version is the advisory's own first_patched_version.

Gotchas

  • Large transfers: Disable TLS inside the app and let Caddy terminate TLS. This avoids double encryption overhead.
  • Dedicated share directory: Do not give Copyparty the whole disk. Mount only the intended share path.
  • Whole-disk share (live choice): this deployment does serve the whole ~91 T array from /w. The volume is mounted :ro in the unit AND the permission flags grant anonymous only r, so no remote write path exists at all now. But note: LAN-direct :3923 is unauthenticated browse/download (anonymous holds r) — Caddy + Anubis + authentik guard only files.franksdank.cloud, not the published port. Tighten to -v /w::r,dank if anonymous LAN reads become unacceptable. (Before 2026-08-31, -v /w::A made the array world-writable on the LAN — see #Command-line interface (ac edition) — and the mount was rw.)
  • Upload tokens scoped per folder: Prevents accidental global write access.
  • CSP nonces (v1.20.17+): Security hardening for JavaScript execution. May break third-party JS plugins (--js-browser / --html-head).
  • Custom thumbnail extractors (v1.20.19+): New thumbex framework. Requires configuration in initcfg.

See Also

Citations