3.2 KiB
Deploying PodcastYes on Dokploy
Containerized deploy: one image, two services (web + worker) via Docker
Compose, a persistent volume for generated assets, an external Postgres, and
no Redis. Dokploy's bundled Traefik handles the domain, TLS, and SSE streaming.
Artifacts: Dockerfile, docker-compose.yml, .dockerignore.
1. Create the app in Dokploy
- New Project → Create Service → Compose.
- Provider: Git →
https://git.serfaty.co/admin/podcastyes, branchmain. - Compose path:
docker-compose.yml.
2. Environment (Dokploy → Environment tab)
These feed both the build args (NEXT_PUBLIC_*) and runtime env. Minimum:
DATABASE_URL=postgresql://user:pass@host:5432/db?schema=public
BETTER_AUTH_SECRET=<openssl rand -base64 32>
BETTER_AUTH_URL=https://your-domain
NEXT_PUBLIC_APP_URL=https://your-domain
OPENAI_API_KEY=...
ELEVENLABS_API_KEY=...
RESEND_API_KEY=... # optional (emails)
GOOGLE_CLIENT_ID=... # optional (OAuth)
GOOGLE_CLIENT_SECRET=...
# Billing (optional until you sell)
STRIPE_SECRET_KEY=...
STRIPE_WEBHOOK_SECRET=...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=...
STRIPE_PRICE_CREATOR_MONTHLY=... # + PRO/AGENCY, _YEARLY
PAYPAL_CLIENT_ID=...
PAYPAL_CLIENT_SECRET=...
PAYPAL_WEBHOOK_ID=...
PAYPAL_API_BASE=https://api-m.paypal.com
PAYPAL_PLAN_CREATOR=... # + PRO/AGENCY
STORAGE_DIR and PORT are set in the compose file — don't override.
3. Domain + SSL
Dokploy → the web service → Domains → add your domain, container port 3000, enable HTTPS (Let's Encrypt). Traefik streams responses, so the episode-generation SSE works with no extra config.
4. Deploy
Hit Deploy. The build installs deps + ffmpeg, runs next build, and starts:
webrunsprisma migrate deploy(applies all migrations) thennext start.workerruns the pg-boss consumer (ffmpeg available in-image). Both share thestoragevolume at/app/storage(mp3/art/exports). Add a volume backup schedule in Dokploy.
5. First admin
Dokploy → web service → Terminal (or docker exec):
npx tsx scripts/make-admin.ts you@email.com
Then visit /admin.
6. Webhooks
- Stripe →
https://your-domain/api/webhooks/stripe(eventscheckout.session.completed,customer.subscription.created/updated/deleted); setSTRIPE_WEBHOOK_SECRET+ theSTRIPE_PRICE_*. - PayPal →
https://your-domain/api/webhooks/paypal(BILLING.SUBSCRIPTION.*); setPAYPAL_WEBHOOK_ID+PAYPAL_PLAN_*.
Redeploys
Push to main → Dokploy auto-deploys (enable the Git webhook), or click Redeploy. Migrations run automatically on each web boot.
Notes
- Assets are served by the app (authed
/api/assets/..., public/api/public/episodes/[shareId]/...) — no separate static route needed. - Scaling: the
workercan be scaled or moved to its own Compose/host pointing at the sameDATABASE_URL; swap local disk for S3/R2 by addinglib/storage/s3.tsand switching the registry inlib/storage/index.ts. - Build args:
NEXT_PUBLIC_*are baked at image-build time; changing them requires a rebuild (Dokploy does this on deploy).