From e4c4f8de66f63bc8b03a8fb274409f6031bee138 Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 2 Mar 2026 21:43:32 +0500 Subject: [PATCH] feat(ui): wire SvelteKit into docker-compose with ui service and env vars --- .env.example | 18 ++++++++++++++++++ docker-compose.yml | 26 ++++++++++++++++++++++++++ ui/Dockerfile | 23 +++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 ui/Dockerfile diff --git a/.env.example b/.env.example index d1e4792..0864f24 100644 --- a/.env.example +++ b/.env.example @@ -39,3 +39,21 @@ KOKORO_URL=http://kokoro:8880 # Single voices: af_bella, af_sky, af_heart, am_adam, … # Mixed voices: af_bella+af_sky or af_bella(2)+af_sky(1) (weighted blend) KOKORO_VOICE=af_bella + +# ── MinIO / S3 object storage ───────────────────────────────────────────────── +MINIO_ROOT_USER=admin +MINIO_ROOT_PASSWORD=changeme123 +MINIO_BUCKET_CHAPTERS=libnovel-chapters +MINIO_BUCKET_AUDIO=libnovel-audio + +# PocketBase admin credentials (used by scraper + UI server-side) +POCKETBASE_ADMIN_EMAIL=admin@libnovel.local +POCKETBASE_ADMIN_PASSWORD=changeme123 + +# ── SvelteKit UI ───────────────────────────────────────────────────────────── +# Port the UI container exposes on the host +UI_PORT=3000 + +# Public MinIO URL reachable from the browser (for audio/presigned URLs) +# In production, point this at your MinIO reverse-proxy or CDN domain. +PUBLIC_MINIO_PUBLIC_URL=http://localhost:9000 diff --git a/docker-compose.yml b/docker-compose.yml index 981700e..50dbdcc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -130,6 +130,32 @@ services: timeout: 5s retries: 3 + # ─── SvelteKit UI ──────────────────────────────────────────────────────────── + ui: + build: + context: ./ui + dockerfile: Dockerfile + container_name: libnovel-ui + restart: unless-stopped + depends_on: + scraper: + condition: service_healthy + pocketbase: + condition: service_healthy + environment: + SCRAPER_API_URL: "http://scraper:8080" + POCKETBASE_URL: "http://pocketbase:8090" + POCKETBASE_ADMIN_EMAIL: "${POCKETBASE_ADMIN_EMAIL:-admin@libnovel.local}" + POCKETBASE_ADMIN_PASSWORD: "${POCKETBASE_ADMIN_PASSWORD:-changeme123}" + PUBLIC_MINIO_PUBLIC_URL: "${PUBLIC_MINIO_PUBLIC_URL:-http://localhost:9000}" + ports: + - "${UI_PORT:-3000}:3000" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:3000/"] + interval: 15s + timeout: 5s + retries: 3 + volumes: static_books: minio_data: diff --git a/ui/Dockerfile b/ui/Dockerfile new file mode 100644 index 0000000..797260b --- /dev/null +++ b/ui/Dockerfile @@ -0,0 +1,23 @@ +FROM node:22-alpine AS builder +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci + +COPY . . +RUN npm run build + +# ── Runtime image ────────────────────────────────────────────────────────────── +FROM node:22-alpine +WORKDIR /app + +# adapter-node produces a standalone build/ +COPY --from=builder /app/build ./build +COPY --from=builder /app/package.json ./ + +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOST=0.0.0.0 + +EXPOSE 3000 +CMD ["node", "build"]