Files
podcastdistributiona/deploy/README.md
T

3.3 KiB

Deploying Podcast Distribution AI 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/podcast-distribution-ai, branch main.
  • 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://podcastdistributionai.com
NEXT_PUBLIC_APP_URL=https://podcastdistributionai.com
EMAIL_FROM=Podcast Distribution AI <noreply@podcastdistributionai.com>
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:

  • web runs prisma migrate deploy (applies all migrations) then next start.
  • worker runs the pg-boss consumer (ffmpeg available in-image). Both share the storage volume 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 (events checkout.session.completed, customer.subscription.created/updated/deleted); set STRIPE_WEBHOOK_SECRET + the STRIPE_PRICE_*.
  • PayPal → https://your-domain/api/webhooks/paypal (BILLING.SUBSCRIPTION.*); set PAYPAL_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 worker can be scaled or moved to its own Compose/host pointing at the same DATABASE_URL; swap local disk for S3/R2 by adding lib/storage/s3.ts and switching the registry in lib/storage/index.ts.
  • Build args: NEXT_PUBLIC_* are baked at image-build time; changing them requires a rebuild (Dokploy does this on deploy).