--- id: TASK-140 title: IPFS integration for backups and generated files status: Done assignee: [] created_date: '2026-04-02 22:11' updated_date: '2026-04-02 22:11' labels: - infra - ipfs - storage dependencies: [] references: - server/ipfs.ts - server/ipfs-routes.ts - server/local-first/backup-store.ts - server/local-first/backup-routes.ts - server/index.ts priority: medium --- ## Description Add IPFS as a redundant storage layer via Kubo (ipfs.jeffemmett.com). Pin encrypted backups and AI-generated files (images, 3D models, zines) to IPFS fire-and-forget. Filesystem remains primary — IPFS failures are non-fatal. API routes at /api/ipfs for status, pin/unpin, and gateway proxy. ## Acceptance Criteria - [x] #1 server/ipfs.ts client library with pin/unpin/status functions - [x] #2 server/ipfs-routes.ts Hono router at /api/ipfs (status, pin, unpin, gateway proxy) - [x] #3 Backup pinning in backup-store.ts (fire-and-forget, CID in manifest) - [x] #4 IPFS URL route in backup-routes.ts (GET /:space/:docId/ipfs) - [x] #5 Generated file pinning with .cid sidecar files for 8 producer endpoints - [x] #6 IPFS_API_URL and IPFS_GATEWAY_URL env vars in docker-compose.yml - [x] #7 Kubo reachable from rspace container via traefik-public network ## Final Summary Implemented IPFS integration for rspace-online. Created server/ipfs.ts (client library) and server/ipfs-routes.ts (API routes at /api/ipfs). Modified backup-store.ts to pin encrypted backups fire-and-forget with CID stored in manifest. Added pinGeneratedFile() helper in server/index.ts called from 8 producer endpoints (3D models, fal.ai images, Gemini/Imagen images, zine pages). Each pinned file gets a .cid sidecar loaded into memory cache on startup. Kubo container is collab-server-ipfs-1 on traefik-public network. Deployed and verified on Netcup. Key deployment discovery: server uses local Gitea registry (localhost:3000/jeffemmett/rspace-online), not compose build — documented in MEMORY.md.