Set up Stuff Stash with Docker Compose, Caddy HTTPS, Dex OIDC, Postgres, SpiceDB, and Garage.
Quick Start
Section titled “Quick Start”Clone the repository:
git clone https://github.com/elsell/stuffstash.gitcd stuffstashCreate a private environment file:
cp .env.example .envStart the stack:
docker compose -f compose.selfhost.yaml upOpen 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.comPassword: passwordThen follow First Inventory.
To build API and web images from your checkout instead of using published release images, use the contributor override:
docker compose -f compose.selfhost.yaml -f compose.selfhost.build.yaml up --buildHostnames And Ports
Section titled “Hostnames And Ports”The default .env.example uses stuffstash.localhost so the browser and Docker
containers can agree on the same OIDC issuer:
| URL | Service |
|---|---|
https://stuffstash.localhost:8081 | Web app |
https://stuffstash.localhost:8080 | API |
https://stuffstash.localhost:5556/dex | Dex issuer |
https://stuffstash.localhost:3900 | Garage 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.
Local HTTPS Certificate
Section titled “Local HTTPS Certificate”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:
mkdir -p .stuffstash/selfhost/caddydocker compose -f compose.selfhost.yaml cp caddy:/data/caddy/pki/authorities/local/root.crt .stuffstash/selfhost/caddy/root.crtThen import .stuffstash/selfhost/caddy/root.crt into your operating system or
browser trust store.
Replace Defaults
Section titled “Replace Defaults”Do not run with the checked-in defaults outside a first local trial. Replace:
| Setting | Why it matters |
|---|---|
| Dex users and static clients | The committed Dex config has first-run accounts only. See Dex Users And Clients. |
POSTGRES_PASSWORD | Protects inventory metadata. |
SPICEDB_POSTGRES_PASSWORD | Protects authorization state. |
STUFF_STASH_SPICEDB_PRESHARED_KEY | Protects the SpiceDB API. |
STUFF_STASH_S3_ACCESS_KEY | Garage/S3 access key used by the API. |
STUFF_STASH_S3_SECRET_KEY | Garage/S3 secret key used by the API. |
STUFF_STASH_PROVIDER_CREDENTIAL_KEY | Encrypts provider credentials and temporary import material. |
Generate the provider credential key with:
openssl rand -base64 32Store 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.
Verify Persistence
Section titled “Verify Persistence”After creating a household, inventory, item, and photo, restart without deleting volumes:
docker compose -f compose.selfhost.yaml downdocker compose -f compose.selfhost.yaml upSign in again. Your inventory and uploaded media should still be available.
To remove containers and all self-host data volumes:
docker compose -f compose.selfhost.yaml down -vOperations Notes
Section titled “Operations Notes”- Back up
selfhost-postgres-data,selfhost-spicedb-postgres-data,selfhost-garage-meta, andselfhost-garage-data. selfhost-postgres-datacontains Stuff Stash metadata.selfhost-spicedb-postgres-datacontains authorization relationships.selfhost-garage-metaandselfhost-garage-datacontain uploaded media metadata and object bytes.selfhost-caddy-datacontains the local Caddy certificate authority and certificates.- Keep
.envand 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.