paperless-ngx-bare-metallisted
Install: claude install-skill jackson2w/claude-code-skills
# Paperless-ngx bare-metal (non-Docker) install
Covers the gap between Paperless-ngx's official bare-metal docs and what actually happens on a
fresh Debian 13 install — first hit 2026-07-18 building a home document-management LXC
(`paperless`, VMID 144, in the `homelab` repo) with no Docker (Gotenberg is Docker-only and has
no bare-metal alternative at all, but that only matters if Office-document conversion is
needed — pure PDF/scan use, the common "paperless" use case, doesn't need it).
## The release tarball's actual layout — don't assume a versioned top-level dir
`paperless-ngx-v<version>.tar.xz` extracts to a top-level directory literally named
`paperless-ngx/` — **not** version-named. `requirements.txt` sits at that root; `manage.py` is
under `src/` inside it (i.e. `paperless-ngx/src/manage.py`). Confirmed by inspecting the actual
tarball contents (`tar -tJf`), not assumed from docs, which don't spell this out.
If you want side-by-side versions (so a future upgrade doesn't clobber a running install),
extract with `--strip-components=1` into a version-named directory of your own choosing, then
symlink a stable path (e.g. `/opt/paperless/src`) to it:
```bash
mkdir -p /opt/paperless-ngx-2.20.15
tar -xJf paperless-ngx-v2.20.15.tar.xz -C /opt/paperless-ngx-2.20.15 --strip-components=1
ln -sfn /opt/paperless-ngx-2.20.15 /opt/paperless/src
```
With Ansible's `unarchive` module, `extra_opts: ["--strip-components=1"]` does the same thing —
`dest` must already exist as a di