# 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. When a Syncthing route is physically nested below the qB root, mount the qB root once and map the exact Syncthing API folder through it: ```yaml 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/Downloads/Sync" = "/data/qb/Sync" } ``` Do **not** additionally mount `/srv/downloads/Sync` at a path beneath `/data/sync`. The override is the authoritative mapping for that folder and keeps qB source files and staging destinations in one mount namespace. Use the folder's normalized API-visible **path** as the override key (for example, Syncthing `~/Downloads/Sync` becomes `/var/syncthing/Downloads/Sync`); do not use the folder ID. Before starting a stack, validate it with: ```sh docker compose config docker compose run --rm archive-client --check-config ``` 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.