Skip to content

Self-Host Operations

Manage certificates, users, backups, and upgrades for Stuff Stash.

Start with Self-Host Stuff Stash. Use this page when you need to change or maintain the installation.

Caddy creates one local certificate authority for the web app, API, Dex, and Garage. Export its root certificate:

Terminal window
mkdir -p .stuffstash/selfhost/caddy
docker compose -f compose.selfhost.yaml cp caddy:/data/caddy/pki/authorities/local/root.crt .stuffstash/selfhost/caddy/root.crt

Copy root.crt to each device that opens Stuff Stash, then import it using the matching instructions below.

macOS
Terminal window
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain .stuffstash/selfhost/caddy/root.crt
Ubuntu or Debian
Terminal window
sudo cp .stuffstash/selfhost/caddy/root.crt /usr/local/share/ca-certificates/stuffstash.crt
sudo update-ca-certificates
Fedora or RHEL
Terminal window
sudo cp .stuffstash/selfhost/caddy/root.crt /etc/pki/ca-trust/source/anchors/stuffstash.crt
sudo update-ca-trust
Windows

Run in an administrator PowerShell window:

Terminal window
Import-Certificate -FilePath .\root.crt -CertStoreLocation Cert:\LocalMachine\Root

Firefox may use its own certificate store. If the warning remains, open Settings → Privacy & Security → Certificates → View Certificates → Authorities, then import the root.

The defaults are reasonable for a trusted home network, but they are public. Replace them before exposing Stuff Stash to a wider network.

Do this before adding data because the clean reset removes the example stack:

  1. Stop and reset with docker compose -f compose.selfhost.yaml down -v.
  2. Replace the Dex users and clients.
  3. Replace every change-me- value in .env and generate a provider key with openssl rand -base64 32.
  4. Run ./scripts/selfhost-preflight.sh --strict.
  5. Start with docker compose -f compose.selfhost.yaml up -d, then trust its new Caddy root.

Keep .env and the private Dex config out of Git. Do not change database or Garage credentials on an installation with data unless you also rotate them in those services.

Reserve the server’s IPv4 address in your router so bookmarks, certificates, and OIDC callbacks do not change. If the address changes before you have data, stop the stack, remove .env and .stuffstash, and run the setup again with the new address.

A local DNS name is optional. Stop the stack, replace the LAN IP everywhere in .env and the private Dex config, run preflight, then start it again. The name must resolve to the server on every client device; trust the new Caddy root if the certificate authority changed.

Back up .env, your private Dex config, and these Docker volumes together:

VolumeContents
stuffstash_selfhost-postgres-dataInventory metadata and audit history
stuffstash_selfhost-spicedb-postgres-dataAuthorization relationships
stuffstash_selfhost-garage-metaGarage object metadata
stuffstash_selfhost-garage-dataUploaded files
stuffstash_selfhost-caddy-dataLocal CA and certificates

Stop the stack before copying the volumes. Start it afterward, and test a restore before relying on the backup.

  1. Back up the files and volumes above.
  2. Download and verify the new bundle in an empty directory.
  3. Copy the new .env.example to .env, then carry over your changed values; do not replace the new file wholesale. Move the private Dex config too.
  4. Stop the old bundle with docker compose -f compose.selfhost.yaml down.
  5. Run ./scripts/selfhost-preflight.sh, then start the new bundle.

The fixed Compose project name reuses the existing volumes. Check the app and an uploaded image after every upgrade. Database migrations may require the pre-upgrade backup to roll back.