Skip to content

Self-Host Stuff Stash

Set up Stuff Stash with Docker Compose, Caddy HTTPS, Dex OIDC, Postgres, SpiceDB, and Garage.

Clone the repository:

Terminal window
git clone https://github.com/elsell/stuffstash.git
cd stuffstash

Create a private environment file:

Terminal window
cp .env.example .env

Start the stack:

Terminal window
docker compose -f compose.selfhost.yaml up

Open https://stuffstash.localhost:8081.

The Compose stack uses Caddy for browser-facing HTTPS. With the default local hostname, your browser may ask you to accept or trust Caddy’s local certificate authority.

Sign in with the first-run Dex account:

Email: owner@example.com
Password: password

Then follow First Inventory.

To build API and web images from your checkout instead of using published release images, use the contributor override:

Terminal window
docker compose -f compose.selfhost.yaml -f compose.selfhost.build.yaml up --build

The default .env.example uses stuffstash.localhost so the browser and Docker containers can agree on the same OIDC issuer:

URLService
https://stuffstash.localhost:8081Web app
https://stuffstash.localhost:8080API
https://stuffstash.localhost:5556/dexDex issuer
https://stuffstash.localhost:3900Garage S3 API

If you run Stuff Stash from another device on your LAN, replace every stuffstash.localhost value in .env and your Dex config with the same LAN IP or DNS name before starting the stack. OIDC is strict: the issuer, web redirect URI, API origin, and browser-visible URLs must agree.

For a public DNS name, point the name at the server and update .env and Dex before starting the stack.

Caddy creates a local certificate authority for stuffstash.localhost. To avoid browser certificate errors across the web app, API, Dex, and Garage, trust that root certificate on the device running the browser:

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

Then import .stuffstash/selfhost/caddy/root.crt into your operating system or browser trust store.

Do not run with the checked-in defaults outside a first local trial. Replace:

SettingWhy it matters
Dex users and static clientsThe committed Dex config has first-run accounts only. See Dex Users And Clients.
POSTGRES_PASSWORDProtects inventory metadata.
SPICEDB_POSTGRES_PASSWORDProtects authorization state.
STUFF_STASH_SPICEDB_PRESHARED_KEYProtects the SpiceDB API.
STUFF_STASH_S3_ACCESS_KEYGarage/S3 access key used by the API.
STUFF_STASH_S3_SECRET_KEYGarage/S3 secret key used by the API.
STUFF_STASH_PROVIDER_CREDENTIAL_KEYEncrypts provider credentials and temporary import material.

Generate the provider credential key with:

Terminal window
openssl rand -base64 32

Store secrets in .env or your secret manager. Do not commit household secrets.

Follow Dex Users And Clients before you rely on the deployment. The bundled Compose topology uses Dex static users from a private config file; it does not include a Dex user-management UI.

After creating a household, inventory, item, and photo, restart without deleting volumes:

Terminal window
docker compose -f compose.selfhost.yaml down
docker compose -f compose.selfhost.yaml up

Sign in again. Your inventory and uploaded media should still be available.

To remove containers and all self-host data volumes:

Terminal window
docker compose -f compose.selfhost.yaml down -v
  • Back up selfhost-postgres-data, selfhost-spicedb-postgres-data, selfhost-garage-meta, and selfhost-garage-data.
  • selfhost-postgres-data contains Stuff Stash metadata.
  • selfhost-spicedb-postgres-data contains authorization relationships.
  • selfhost-garage-meta and selfhost-garage-data contain uploaded media metadata and object bytes.
  • selfhost-caddy-data contains the local Caddy certificate authority and certificates.
  • Keep .env and your private Dex config out of Git.
  • Use URL-safe database passwords, or percent-encode reserved characters in connection strings.
  • Use a real DNS name and publicly trusted certificate before exposing the deployment outside your machine.
  • Record image versions before upgrades and run the stack after each upgrade so migrations can complete.