feat: optimize Docker startup with Next.js standalone output and proper migrations
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled

- Add `output: standalone` to next.config.js for faster cold start
- Rebuild runner stage around standalone bundle (node server.js instead of pnpm start)
- Replace prisma db push with prisma migrate deploy (proper migration workflow)
- Remove npx/pnpm at runtime, use direct binary paths
- Add HOSTNAME=0.0.0.0 for standalone server to listen on all interfaces
- Fix next.config.js not copied in builder stage
- Update README: pnpm instead of yarn, correct ports, full env vars documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 21:52:49 +01:00
parent 7e4c48469a
commit 8d1f91d636
6 changed files with 114 additions and 33 deletions

View File

@@ -17,7 +17,7 @@ COPY package.json pnpm-lock.yaml ./
COPY prisma ./prisma
# Copy configuration files
COPY tsconfig.json .eslintrc.json ./
COPY tsconfig.json .eslintrc.json next.config.js ./
COPY tailwind.config.ts postcss.config.js ./
# Install dependencies with pnpm using cache mount for store
@@ -43,22 +43,20 @@ WORKDIR /app
# Install OpenSSL (required by Prisma)
RUN apk add --no-cache openssl libc6-compat
# Copy package files and prisma schema
COPY package.json pnpm-lock.yaml ./
COPY prisma ./prisma
# Copy standalone output (server.js + minimal node_modules)
COPY --from=builder /app/.next/standalone ./
# Enable pnpm
RUN corepack enable && corepack prepare pnpm@9.0.0 --activate
# Copy static assets and public directory
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
# Copy the entire node_modules from builder (includes Prisma Client)
# Copy full node_modules for Prisma CLI (pnpm symlinks prevent cherry-picking)
COPY --from=builder /app/node_modules ./node_modules
# Copy built application from builder stage
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/next-env.d.ts ./
COPY --from=builder /app/tailwind.config.ts ./
# Copy prisma schema and init scripts
COPY prisma ./prisma
COPY --from=builder /app/scripts ./scripts
COPY package.json ./
# Copy entrypoint script
COPY docker-entrypoint.sh ./
@@ -76,6 +74,7 @@ USER nextjs
# Set environment variables
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV HOSTNAME="0.0.0.0"
# Expose the port the app runs on
EXPOSE 3000

View File

@@ -74,7 +74,7 @@ A modern web application for reading digital comics, built with Next.js 14 and t
## 🛠 Prerequisites
- Node.js 20.x or higher
- Yarn 1.22.x or higher
- pnpm 9.x or higher
- Docker and Docker Compose (optional)
## 📦 Installation
@@ -91,7 +91,7 @@ cd stripstream
2. Install dependencies
```bash
yarn install
pnpm install
```
3. Copy the example environment file and adjust it to your needs
@@ -103,7 +103,7 @@ cp .env.example .env.local
4. Start the development server
```bash
yarn dev
pnpm dev
```
### With Docker (Build Local)
@@ -121,7 +121,7 @@ cd stripstream
docker-compose up --build
```
The application will be accessible at `http://localhost:3000`
The application will be accessible at `http://localhost:3020`
### With Docker (DockerHub Image)
@@ -130,18 +130,24 @@ You can also use the pre-built image from DockerHub without cloning the reposito
1. Create a `docker-compose.yml` file:
```yaml
version: '3.8'
services:
app:
image: julienfroidefond32/stripstream:latest
ports:
- "3000:3000"
environment:
- NODE_ENV=production
# Add your environment variables here or use an .env file
# Required
- NEXTAUTH_SECRET=your_secret_here # openssl rand -base64 32
- NEXTAUTH_URL=http://localhost:3000
# Optional — defaults shown
# - NODE_ENV=production
# - DATABASE_URL=file:/app/prisma/data/stripstream.db
# - ADMIN_DEFAULT_PASSWORD=Admin@2025
# - AUTH_TRUST_HOST=true
# - KOMGA_MAX_CONCURRENT_REQUESTS=5
volumes:
- ./data:/app/data
- ./data:/app/prisma/data
restart: unless-stopped
```
@@ -155,11 +161,10 @@ The application will be accessible at `http://localhost:3000`
## 🔧 Available Scripts
- `yarn dev` - Starts the development server
- `yarn build` - Creates a production build
- `yarn start` - Runs the production version
- `yarn lint` - Checks code with ESLint
- `yarn format` - Formats code with Prettier
- `pnpm dev` - Starts the development server
- `pnpm build` - Creates a production build
- `pnpm start` - Runs the production version
- `pnpm lint` - Checks code with ESLint
- `./docker-push.sh [tag]` - Build and push Docker image to DockerHub (default tag: `latest`)
### Docker Push Script

View File

@@ -1,15 +1,11 @@
#!/bin/sh
set -e
echo "📁 Ensuring data directory exists..."
mkdir -p /app/data
echo "🔄 Pushing Prisma schema to database..."
npx prisma db push --skip-generate --accept-data-loss
echo "🔄 Applying database migrations..."
./node_modules/.bin/prisma migrate deploy
echo "🔧 Initializing database..."
node scripts/init-db.mjs
echo "🚀 Starting application..."
exec pnpm start
exec node server.js

View File

@@ -1,5 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,

View File

@@ -0,0 +1,77 @@
-- CreateTable
CREATE TABLE "users" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"roles" JSONB NOT NULL DEFAULT ["ROLE_USER"],
"authenticated" BOOLEAN NOT NULL DEFAULT true,
"activeProvider" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "komgaconfigs" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"userId" INTEGER NOT NULL,
"url" TEXT NOT NULL,
"username" TEXT NOT NULL,
"authHeader" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "komgaconfigs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "stripstreamconfigs" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"userId" INTEGER NOT NULL,
"url" TEXT NOT NULL,
"token" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "stripstreamconfigs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "preferences" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"userId" INTEGER NOT NULL,
"showThumbnails" BOOLEAN NOT NULL DEFAULT true,
"showOnlyUnread" BOOLEAN NOT NULL DEFAULT false,
"displayMode" JSONB NOT NULL,
"background" JSONB NOT NULL,
"readerPrefetchCount" INTEGER NOT NULL DEFAULT 5,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "preferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "favorites" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"userId" INTEGER NOT NULL,
"seriesId" TEXT NOT NULL,
"provider" TEXT NOT NULL DEFAULT 'komga',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "favorites_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
-- CreateIndex
CREATE UNIQUE INDEX "komgaconfigs_userId_key" ON "komgaconfigs"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "stripstreamconfigs_userId_key" ON "stripstreamconfigs"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "preferences_userId_key" ON "preferences"("userId");
-- CreateIndex
CREATE INDEX "favorites_userId_idx" ON "favorites"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "favorites_userId_provider_seriesId_key" ON "favorites"("userId", "provider", "seriesId");

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"