Obelica Docs
Applicazioni

Tulpa Studio

Scheda operativa per tulpa-studio

Tulpa Studio

Stato operativo

VPS e router produzione gia' preparati, ma il dominio e' gestito dal cliente. Cutover in attesa di coordinamento esterno.

Runtime e deploy

VoceValore
Repo/opt/obelica/repos/tulpa-studio
Containertulpa-studio
StackNext.js
Porta interna3000
Env file/opt/obelica/secrets/apps/tulpa-studio.env
Deploynext-docker

DNS e TLS

Dominio produzione: tulpastudio.com, www.tulpastudio.com.

Router Traefik include staging e produzione. Finche' il DNS resta su terzi/Vercel, Traefik puo' registrare errori ACME attesi per tulpastudio.com.

Record importanti da preservare nella zona target: Google Workspace, Amazon SES, Lovable, Canva e record commercial, secondo runbook DNS DigitalOcean.

Database, storage e backup

Database su DigitalOcean Managed PostgreSQL. Storage migrato verso DigitalOcean Spaces secondo documentazione storage. Backup Obelica copre repo/config; database e Spaces seguono policy dedicate.

Verifiche

Staging VPS disponibile su tulpa-studio.vps.obelica.com.

Router Traefik — modifica 2026-07-03

I domini production sono stati RIMOSSI dal router Traefik: il DNS punta ancora all'hosting precedente e la challenge ACME falliva in loop ogni ora (rischio rate-limit Let's Encrypt, 22 errori/24h sui log Traefik). Il compose contiene un commento AL CUTOVER accanto alla rule con le righe esatte da riattivare (Host production + label tls.domains). Al cutover: riattivare le label, docker compose up -d, verificare emissione certificato.

Punti aperti

  • attendere che il cliente cambi DNS/nameserver;
  • verificare certificato Let's Encrypt dopo il cutover;
  • aggiornare questa scheda con esito finale.
  • al cutover: riattivare i domini production nel router Traefik (commento AL CUTOVER nel compose).

Upload media / Storage Spaces (risolto 2026-07-19)

Gli upload dell'area admin (media library) usano DigitalOcean Spaces via presigned URL (src/lib/storage/servercreateUploadTarget, client src/lib/storage/client-upload). Il client chiede un target di upload alla route, riceve un uploadUrl presigned (ACL public-read) e fa il PUT direttamente su Spaces.

Bug risolto: in produzione SPACES_ACCESS_KEY_ID e SPACES_SECRET_ACCESS_KEY erano vuote ("") — le chiavi c'erano ma i valori no. Con STORAGE_PROVIDER=spaces, createUploadTarget chiamava requireEnv('SPACES_ACCESS_KEY_ID') e lanciava Missing required environment variable: SPACES_ACCESS_KEY_ID, quindi la generazione del target falliva e l'upload non partiva. Nessuno l'aveva ancora notato (nessun errore nei log: feature non usata di recente).

Fix (env-only, nessun rebuild): popolate le due credenziali riusando quelle del bucket condiviso obelica-assets-prod (già in uso da wash-dog), backup dell'env salvato accanto al file, container ricreato (docker compose up -d --force-recreate --no-build).

Verifica: route upload-target raggiungibile (401 senza auth = modulo storage ok, nessun problema di bundling del presigner); flusso presigned reale testato con le credenziali → PUT 200 + GET pubblica 200 image/png sul prefisso dell'app.

Nota: stesso identico problema che aveva sonja-trekking (vedi sua scheda). Tutte le app condividono il bucket obelica-assets-prod, namespacato con SPACES_APP_PREFIX.

Addendum tulpa: la route /api/cms/media/upload usa ancora @vercel/blob/client come fallback quando il provider non e spaces; con STORAGE_PROVIDER=spaces quel path resta inattivo. Il token BLOB_READ_WRITE_TOKEN residuo e quindi morto. Eventuali media storici in DB potrebbero puntare a URL blob.vercel-storage.com (vedi script migrate).

On this page