75 lines
3.1 KiB
Markdown
75 lines
3.1 KiB
Markdown
# Production deployment
|
|
|
|
These files are the non-secret, host-specific deployment manifests for the
|
|
initial x1/x2/lithium topology and the later helium archive node.
|
|
|
|
- Install the x1 and x2 files as
|
|
`~/compose/ArchiveControl-cache/{compose.yaml,client.toml}`.
|
|
- Install the lithium files as
|
|
`~/compose/ArchiveControl-archive/{compose.yaml,client.toml}`.
|
|
- The helium directory contains three isolated compose-project manifests. Install
|
|
them under `~/Repositories/compose/{qbittorrent-helium,syncthing-helium,ArchiveControl-archive}`
|
|
as described in `helium/README.md`.
|
|
- Create sibling `state`, `backups`, and `secrets` directories owned by the
|
|
configured container UID/GID.
|
|
- Secret files are never committed. Each `secrets` directory contains
|
|
`archive_control_token`, `qb_password`, and `syncthing_api_key`, each a
|
|
regular non-empty file with mode `0600`.
|
|
|
|
## Hardlink-safe bind-mount topology
|
|
|
|
For an archive source, the qB content path and every Syncthing route used for
|
|
staging must resolve through the **same container mount**. Matching host
|
|
filesystem device IDs alone is insufficient: two separate Docker bind mounts
|
|
have different mount IDs and `link(2)` may return `EXDEV` across them. The
|
|
client deliberately treats that case as copy-only and performs a full payload
|
|
free-space check.
|
|
|
|
Automatic routes always use the Syncthing API path `routes/<route-id>`. Bind
|
|
that path from a dedicated directory beneath the qB data root, then map the
|
|
same path through the qB client mount:
|
|
|
|
```yaml
|
|
# Syncthing compose project
|
|
volumes:
|
|
- /srv/syncthing-config:/var/syncthing
|
|
- /srv/downloads/.archive-control-routes:/var/syncthing/routes
|
|
|
|
# Archive Control client compose project
|
|
volumes:
|
|
- /srv/downloads:/data/qb
|
|
- /srv/syncthing-config:/data/sync
|
|
```
|
|
|
|
```toml
|
|
[syncthing]
|
|
api_root = "/var/syncthing"
|
|
local_root = "/data/sync"
|
|
local_path_overrides = { "/var/syncthing/routes" = "/data/qb/.archive-control-routes" }
|
|
```
|
|
|
|
Do **not** mount the route directory separately into the client. The override
|
|
is the authoritative mapping and keeps qB source files and automatic route
|
|
folders in one mount namespace. Existing manually configured Syncthing folders
|
|
below the qB tree may retain their own exact overrides. Use API-visible paths,
|
|
not Syncthing folder IDs, as override keys.
|
|
|
|
Before starting a stack, validate its config and then run the generic host
|
|
preflight with that machine's own paths and container names:
|
|
|
|
```sh
|
|
docker compose config
|
|
docker compose run --rm archive-client --check-config
|
|
python3 scripts/preflight-deployment.py --help
|
|
```
|
|
|
|
The check is fail-fast and performs local permission, filesystem, sparse-file,
|
|
hard-link, and reflink probes. Normal startup additionally probes the local
|
|
qBittorrent and Syncthing APIs before registration.
|
|
|
|
`scripts/preflight-deployment.py` is deliberately topology-agnostic: pass the
|
|
host's `client.toml` and its client, qBittorrent, and Syncthing container names.
|
|
It resolves Docker mounts rather than assuming project names or host paths. It
|
|
also catches a common fatal error: a Syncthing `api_root` that names its config
|
|
volume rather than the mounted shared-data tree.
|