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.
184 lines
8.7 KiB
Markdown
184 lines
8.7 KiB
Markdown
---
|
|
type: reference
|
|
description: "Copyparty is a lightweight file server and media streamer that runs as a single Python binary."
|
|
tags:
|
|
- dankserver
|
|
- copyparty
|
|
timestamp: 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 `exec`s `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)
|
|
|
|
```yaml
|
|
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
|
|
|
|
- [[Dankserver Stack]]
|
|
- [[Caddy]] — TLS termination and authentication in front
|
|
- [[ARR-Stack]] — Copyparty as a viewer alongside automated download management
|
|
|
|
## Citations
|
|
|
|
- GitHub Security Advisories, `9001/copyparty` —
|
|
https://github.com/9001/copyparty/security/advisories (accessed 2026-10-19)
|
|
each row's patched version read from `first_patched_version` in the
|
|
`https://api.github.com/advisories/<GHSA-id>` response.
|