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

View File

@@ -74,7 +74,7 @@ A modern web application for reading digital comics, built with Next.js 14 and t
## 🛠 Prerequisites ## 🛠 Prerequisites
- Node.js 20.x or higher - Node.js 20.x or higher
- Yarn 1.22.x or higher - pnpm 9.x or higher
- Docker and Docker Compose (optional) - Docker and Docker Compose (optional)
## 📦 Installation ## 📦 Installation
@@ -91,7 +91,7 @@ cd stripstream
2. Install dependencies 2. Install dependencies
```bash ```bash
yarn install pnpm install
``` ```
3. Copy the example environment file and adjust it to your needs 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 4. Start the development server
```bash ```bash
yarn dev pnpm dev
``` ```
### With Docker (Build Local) ### With Docker (Build Local)
@@ -121,7 +121,7 @@ cd stripstream
docker-compose up --build 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) ### 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: 1. Create a `docker-compose.yml` file:
```yaml ```yaml
version: '3.8'
services: services:
app: app:
image: julienfroidefond32/stripstream:latest image: julienfroidefond32/stripstream:latest
ports: ports:
- "3000:3000" - "3000:3000"
environment: environment:
- NODE_ENV=production # Required
# Add your environment variables here or use an .env file - 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: volumes:
- ./data:/app/data - ./data:/app/prisma/data
restart: unless-stopped restart: unless-stopped
``` ```
@@ -155,11 +161,10 @@ The application will be accessible at `http://localhost:3000`
## 🔧 Available Scripts ## 🔧 Available Scripts
- `yarn dev` - Starts the development server - `pnpm dev` - Starts the development server
- `yarn build` - Creates a production build - `pnpm build` - Creates a production build
- `yarn start` - Runs the production version - `pnpm start` - Runs the production version
- `yarn lint` - Checks code with ESLint - `pnpm lint` - Checks code with ESLint
- `yarn format` - Formats code with Prettier
- `./docker-push.sh [tag]` - Build and push Docker image to DockerHub (default tag: `latest`) - `./docker-push.sh [tag]` - Build and push Docker image to DockerHub (default tag: `latest`)
### Docker Push Script ### Docker Push Script

View File

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

View File

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