Skip to main content

Setting up the OS

SSH Access​

Via pass-cli's SSH agent — no private key ever written to disk, matching the rest of this project's credential handling. Loads the key straight from the <prefix>-ssh-infrastructure-key vault item into an agent socket; SSH talks to the socket, not a file:

pass-cli ssh-agent daemon start --vault-name Tech
export SSH_AUTH_SOCK=~/.ssh/proton-pass-agent.sock
ssh debian@<ipv4>

The daemon start form persists in the background, so it survives across terminal sessions — pass-cli ssh-agent daemon status to confirm it's alive. export SSH_AUTH_SOCK=... still needs to happen in each new shell (or add it to your shell profile) so ssh knows where to find it.

Debian cloud images default to a debian user with sudo, not root.

Console Recovery​

Set a root password too — purely for local console access (sulogin) if the box ever drops into emergency mode (a failed mount, for instance), not for SSH: PermitRootLogin and PasswordAuthentication stay whatever they're configured as regardless, this doesn't touch network access at all. Without it, emergency mode is a genuine dead end — sulogin has no password to check against, and the only way back in is a bootloader-level workaround (interrupting GRUB, booting with init=/bin/bash):

sudo passwd root

Save whatever you set in Proton Pass, as <prefix>-server-<name>-root-password — alongside everything else on this box, not a value that should only exist in your head.

Disk Setup​

OpenTofu attaches the data volume as raw block storage — formatting and mounting it is an OS-level step outside its scope. Do this before installing Docker or Coolify: the daemon config points data-root at /mnt/data, which needs to already exist and be mounted first.

  1. Confirm the device — /dev/sdb here, since this image uses SCSI disk bus rather than virtio (so sda/sdb, not vda/vdb). Check by size, not just letter: SCSI device-letter assignment isn't guaranteed to stay the same across boots, so this is only reliable as a one-time, live-verified check, not something to hardcode anywhere:

    lsblk
  2. Format it ext4 — it's a blank volume, nothing to preserve. The device name is fine to use directly here, since this step is one-time and live-verified against what lsblk just showed:

    sudo mkfs.ext4 /dev/sdb
  3. Get its UUID — this, not the device name, is what stays correct across reboots:

    sudo blkid /dev/sdb
  4. Create the mount point:

    sudo mkdir -p /mnt/data
  5. Persist the mount using the UUID from step 3, not the device name. /dev/sdb isn't a stable identifier — which physical disk the kernel assigns that name to on any given boot depends on enumeration order, which can and does shift. Referencing it directly in /etc/fstab risks the mount silently landing on the wrong disk on some future reboot — exactly what the root filesystem's own fstab entry already avoids, by using PARTUUID= instead of a device path:

    echo 'UUID=<uuid-from-step-3> /mnt/data ext4 defaults 0 2' | sudo tee -a /etc/fstab
  6. Mount it — this reads the entry straight from /etc/fstab, confirming it's valid before relying on it at the next boot:

    sudo mount /mnt/data