# Migration Notes: bare metal → Proxmox ## Deploy order Most stacks are independent — deploy in any order. `cloudflared` is the one exception: it attaches to networks owned by `caddy`, `guacamole`, `stash`, and `copyparty`, so bring those four up first, then `cloudflared` last. ```bash cd caddy && docker compose up -d && cd .. cd guacamole && docker compose up -d && cd .. cd stash && docker compose up -d && cd .. cd copyparty && docker compose up -d && cd .. cd cloudflared && docker compose up -d && cd .. # then the rest, any order ``` Running `docker compose up -d` from inside a folder named e.g. `caddy/` auto-names the project `caddy`, which recreates the network `caddy_default` — matching the original names your other containers (like cloudflared) expect. ## Bind-mount directories to copy over (rsync these first) ``` /opt/adguardhome/conf /opt/adguardhome/work /etc/caddy/Caddyfile /var/www/html /etc/copyparty /home/sprite (used by copyparty) /srv/crafty /srv/media /srv/stash /srv/crafty/backups /srv/crafty/config /srv/crafty/import /srv/crafty/logs /srv/crafty/servers /etc/stash /etc/jellyfin /srv/downloads ``` Example: ```bash rsync -avz /srv/media/ user@proxmox-vm:/srv/media/ ``` ## Named volumes with real data to migrate These aren't just caches — copy the underlying data, don't just recreate empty: - `caddy_caddy_config`, `caddy_caddy_data` - `guacamole_guac-db-data` (your Guacamole MySQL DB — this is the one that actually matters) - `guacamole_initdb` - `pip` (stash) - `portainer_data` (your Portainer stacks/settings) `jellyfin` (cache) volume can be left empty/recreated on the new host — it's just transcode cache. To copy a named volume's data: ```bash docker run --rm -v :/from -v /tmp/volbackup:/to alpine \ sh -c "cd /from && tar cf /to/.tar ." # copy the tar to the new host, then: docker run --rm -v :/to -v /tmp/volbackup:/from alpine \ sh -c "cd /to && tar xf /from/.tar" ``` ## Secrets exposed in the original autocompose dump — rotate these The raw output had these in plaintext. Since they've now passed through a chat log, treat them as compromised and rotate before/after migrating: - Cloudflare tunnel token (`cloudflared`) - MySQL root/user password (`guacamole-db` — currently `guacamole`/`guacamole`, worth changing regardless) - Honeygain email + password - playit.gg secret key - TraffMonetizer token - PacketStream CID (less sensitive, but still your account identifier) I've replaced these with `REPLACE_WITH_...` placeholders in the split files — move them into a `.env` file per stack rather than hardcoding, e.g.: ``` # caddy/.env (git-ignored) CF_TUNNEL_TOKEN=xxxx ``` ```yaml environment: - "TOKEN=${CF_TUNNEL_TOKEN}" ``` ## GPU passthrough `jellyfin` and `stash` both pass through `/dev/dri` for hardware transcoding. On Proxmox this only works if the host's iGPU is passed into whichever VM/LXC runs these containers: - **VM**: PCI passthrough of the GPU, or use Proxmox's mediated device (SR-IOV/GVT-g) if supported by your iGPU - **LXC (privileged)**: bind-mount `/dev/dri` from the Proxmox host into the container config If you skip this, both will silently fall back to software transcoding — functional but much slower. ## Networking mode notes - `jellyfin` and `playit` use `network_mode: host` — fine in a VM, but if you run them in an LXC on Proxmox this shares the *host's* network namespace, which is usually not what you want. Prefer a VM for these two, or switch to bridge + explicit port mappings. - `crafty_container`, `honeygain`, `metube`, `portainer`, `psclient`, `tm`, `watchtower` all just use the default Docker bridge — no special handling needed.