Files
serverAppConfigs/serverAppConfigs-docs/Dankserver/Copyparty.md
T
Frank 7190720a9e docs(dankserver): copyparty doc matches the ac edition's real interface
The page claimed an env-var interface (COPAY_PASS/COPAY_MODE) and a /data
volume convention that this image does not implement: the ac edition consumes
accounts and volumes as argv flags (-a USER:PASS, -v SRC:DST:PERMS), serves
the LUKS array at /w, and answers HTTP 500 with its own error page when zero
volumes are configured. Image ref corrected to copyparty-ac (bare latest tag
does not exist on ghcr).
2026-08-29 03:39:23 -07:00

122 lines
5.0 KiB
Markdown

# 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 — **Hostname:** `files.dankserver.local` — **Docs:** https://github.com/9001/copyparty
## Facts
| Item | Value |
|------|-------|
| Latest version | v1.20.21 (2026-08) |
| 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) |
| 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::A"]
```
`-a` takes `USER:PASS`; `-v` takes `SRC:DST:PERMS:FLAGS` — here volume `/w`
with the `A` ("all") flag for the `dank` account, nothing for anonymous.
### 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 (2026-08-29): the whole LUKS array is served at URL root `/w`
via the `-v /w::A` flag — account `dank` holds the `A` (all) flag, anonymous
gets nothing. The compose bind mount is
`/mnt/entropy:/w` (host path → container path); the ac edition serves its
volume roots from argv, not from a `/data` convention.
## Docker Compose
```yaml
services:
copyparty:
image: ghcr.io/9001/copyparty:latest
container_name: copyparty
restart: unless-stopped
environment:
COPAY_PASS: "${COPAY_PASS}"
COPAY_MODE: rw
ports:
- "3923:3923"
volumes:
- /opt/copyparty/data:/data
healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3923/')"]
interval: 30s
timeout: 10s
retries: 3
```
## 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 | CVE | Issue |
|---------|-----|-------|
| v1.20.19 | GHSA-phv8-wgjp-g4p9 | FTP upload outside volume |
| v1.20.17 | GHSA-x5pq-m9p8-f4vx | dirkey/filekey confusion |
| v1.20.9 | CVE-2026-27948 / GHSA-62cr-6wp5-q43h | XSS via file upload |
Upgrade to v1.20.19+ to cover all known CVEs. The dirkey fix (v1.20.17) matters if using both `dirkeys` and `filekeys`.
## 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 (`-v /w::A`). Safe only because anonymous gets zero permissions —
every request authenticates against the `dank` account first, and Caddy +
Anubis + authentik sit in front (see [[Anubis]], [[Authentik]]). Strip the
`A` flag or drop the account and the array becomes world-writable again.
- **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