Full self-hosted click track generator for cover bands. Core technical pieces implemented: - CTP (Click Track Protocol) TypeScript schema, Zod validator, and WAV renderer (44.1 kHz, 16-bit PCM, accented downbeats, ramp sections) - MusicBrainz API client with 1 req/s rate limiting - PostgreSQL schema (songs, tempo_maps, registry_sync_log) with triggers - Git registry sync logic (clone/pull → validate CTP → upsert DB) - Next.js 14 App Router: search page, track page, API routes (/api/songs, /api/tracks, /api/generate) - UI components: SearchBar, SongResult, TempoMapEditor, ClickTrackPlayer (Web Audio API in-browser playback + WAV download) - Docker Compose stack: app + postgres + redis + nginx + registry-sync - Multi-stage Dockerfile with standalone Next.js output - .env.example documenting all configuration variables - README with setup instructions, CTP format spec, and API reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
2.7 KiB
Docker
62 lines
2.7 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
# Stage 1 — deps: install all node_modules
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
FROM node:20-alpine AS deps
|
|
|
|
RUN apk add --no-cache libc6-compat git
|
|
|
|
WORKDIR /app
|
|
|
|
COPY package.json package-lock.json* yarn.lock* pnpm-lock.yaml* ./
|
|
|
|
RUN \
|
|
if [ -f package-lock.json ]; then npm ci; \
|
|
elif [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm install --frozen-lockfile; \
|
|
else echo "No lockfile found." && npm install; \
|
|
fi
|
|
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
# Stage 2 — builder: compile Next.js production build
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
FROM node:20-alpine AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
|
|
# Disable Next.js telemetry during build
|
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
|
|
RUN npm run build
|
|
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
# Stage 3 — runner: minimal production image
|
|
# ────────────────────────────────────────────────────────────────────────────────
|
|
FROM node:20-alpine AS runner
|
|
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV=production
|
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
|
|
RUN addgroup --system --gid 1001 nodejs \
|
|
&& adduser --system --uid 1001 nextjs
|
|
|
|
# Copy only what's needed to run
|
|
COPY --from=builder /app/public ./public
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
|
|
USER nextjs
|
|
|
|
EXPOSE 3000
|
|
|
|
ENV PORT=3000
|
|
ENV HOSTNAME="0.0.0.0"
|
|
|
|
CMD ["node", "server.js"]
|