From 15c2d4713fb28b72cf160f305e23ebef52c9fa99 Mon Sep 17 00:00:00 2001 From: OpenClaw Bot Date: Mon, 23 Feb 2026 22:10:49 -0600 Subject: [PATCH] Signed-off-by: OpenClaw Bot --- Dockerfile | 39 ++++++++++++++++++ docker-compose.yml | 28 +++++++++++++ memory/2026-02-23-podcast-task.md | 66 +++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 memory/2026-02-23-podcast-task.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bbb0385 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +FROM node:22-alpine AS deps +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci + +FROM node:22-alpine AS builder +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY package.json package-lock.json ./ +COPY next.config.ts tsconfig.json postcss.config.mjs eslint.config.mjs ./ +COPY public ./public +COPY src ./src +COPY data ./data + +RUN npm run build + +FROM node:22-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=4002 +ENV HOSTNAME=0.0.0.0 + +COPY package.json package-lock.json ./ +COPY --from=deps /app/node_modules ./node_modules +RUN npm prune --omit=dev + +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/public ./public +COPY --from=builder /app/data ./data + +EXPOSE 4002 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD wget -q -O - http://127.0.0.1:4002/favicon.ico > /dev/null || exit 1 + +CMD ["npm", "run", "start", "--", "-p", "4002", "-H", "0.0.0.0"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f78a1af --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +services: + blog-backup: + container_name: blog-backup + build: + context: . + dockerfile: Dockerfile + pull_policy: build + ports: + - "4002:4002" + environment: + NODE_ENV: production + PORT: "4002" + HOSTNAME: 0.0.0.0 + env_file: + - .env.production + volumes: + - blog_backup_runtime:/app/.runtime + healthcheck: + test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:4002/favicon.ico > /dev/null || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + restart: unless-stopped + +volumes: + blog_backup_runtime: + driver: local diff --git a/memory/2026-02-23-podcast-task.md b/memory/2026-02-23-podcast-task.md new file mode 100644 index 0000000..b46e79a --- /dev/null +++ b/memory/2026-02-23-podcast-task.md @@ -0,0 +1,66 @@ +# Daily Digest Podcast - Implementation Complete + +**Task:** Research and build a digital podcast solution for the Daily Digest blog +**Status:** ✅ Complete (Ready for Review) +**Date:** 2026-02-23 + +## What Was Delivered + +### 1. Research Findings +- **TTS Providers**: OpenAI TTS ($2-4/month, best quality) vs Piper (free, local) vs macOS say (free, basic) +- **Audio Storage**: Supabase Storage (free tier 1GB) +- **RSS Feed**: Next.js API route with iTunes extensions +- **Integration**: Async TTS generation triggered after digest post + +### 2. Implementation + +**Core Services:** +- `src/lib/tts.ts` - Multi-provider TTS abstraction (OpenAI, Piper, macOS) +- `src/lib/storage.ts` - Supabase Storage audio upload/management +- `src/lib/podcast.ts` - RSS generation utilities + +**API Endpoints:** +- `GET /api/podcast/rss` - RSS 2.0 feed for podcast apps +- `POST /api/digest` - Updated to trigger async TTS generation + +**UI Pages:** +- `/podcast` - Web audio player with episode listing +- Updated blog post view with inline audio player +- Added podcast link to header navigation + +**Scripts:** +- `npm run generate-tts -- ` - Generate audio for specific post +- `npm run generate-tts:all` - Batch generate for all missing posts + +**Documentation:** +- `PODCAST_SETUP.md` - Complete setup guide +- `PODCAST_ARCHITECTURE.md` - Architecture overview +- `PODCAST_SUMMARY.md` - Implementation summary + +### 3. Key Features +- ✅ Automatic TTS when new digest posted +- ✅ RSS feed compatible with Apple Podcasts, Spotify +- ✅ Web audio player on podcast page +- ✅ Multiple TTS provider options +- ✅ Free tier coverage (Supabase storage + Piper TTS = $0) +- ✅ Async processing (doesn't block post creation) + +### 4. URLs +- RSS Feed: `https://blog-backup-two.vercel.app/api/podcast/rss` +- Podcast Page: `https://blog-backup-two.vercel.app/podcast` + +### 5. Next Steps for Deployment +1. Run SQL to add audio columns to database +2. Add `ENABLE_TTS=true` and `OPENAI_API_KEY` to Vercel env vars +3. Deploy: `npm run build && vercel --prod` +4. Submit RSS to Apple Podcasts, Spotify + +### 6. Files Modified/Created +- 13 files changed, 1792 insertions +- Committed to main branch + +## Cost Analysis +- OpenAI TTS: ~$2-4/month (optional) +- Piper/macOS TTS: $0 +- Supabase Storage: $0 (within free tier) +- Total: $0-4/month depending on TTS provider