feat: optimize Docker startup with Next.js standalone output and proper migrations
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled
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:
23
Dockerfile
23
Dockerfile
@@ -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
|
||||
|
||||
33
README.md
33
README.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: "standalone",
|
||||
webpack: (config) => {
|
||||
config.resolve.fallback = {
|
||||
...config.resolve.fallback,
|
||||
|
||||
77
prisma/migrations/20260311203728_init/migration.sql
Normal file
77
prisma/migrations/20260311203728_init/migration.sql
Normal 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");
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal 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"
|
||||
Reference in New Issue
Block a user