Skip to content

Instantly share code, notes, and snippets.

@malteneuss
Created April 28, 2022 19:43
Show Gist options
  • Save malteneuss/a7fafae22ea81e778654f72c16fe58d3 to your computer and use it in GitHub Desktop.
Save malteneuss/a7fafae22ea81e778654f72c16fe58d3 to your computer and use it in GitHub Desktop.

Revisions

  1. malteneuss created this gist Apr 28, 2022.
    39 changes: 39 additions & 0 deletions Dockerfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    # Adapted from https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
    # Install dependencies only when needed
    FROM node:16-alpine AS deps
    # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
    RUN apk add --no-cache libc6-compat
    WORKDIR /app
    COPY package.json package-lock.json ./
    RUN npm ci

    # Rebuild the source code only when needed
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY --from=deps /app/node_modules ./node_modules
    COPY . .
    ENV NEXT_TELEMETRY_DISABLED 1
    RUN npx prisma generate # <---important to support Prisma query engine in Alpine Linux in final image
    RUN npm run build

    # Production image, copy all the files and run next
    FROM node:16-alpine AS runner
    WORKDIR /app
    ENV NODE_ENV production
    ENV NEXT_TELEMETRY_DISABLED 1
    RUN addgroup --system --gid 1001 nodejs
    RUN adduser --system --uid 1001 nextjs
    # You only need to copy next.config.js if you are NOT using the default configuration
    # COPY --from=builder /app/next.config.js ./
    COPY --from=builder /app/public ./public
    COPY --from=builder /app/package.json ./package.json
    # Automatically leverage output traces to reduce image size
    # https://nextjs.org/docs/advanced-features/output-file-tracing
    COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
    COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
    COPY --chown=nextjs:nodejs prisma ./prisma/ # <---important to support Prisma DB migrations in docker-bootstrap-app.sh
    COPY --chown=nextjs:nodejs docker-bootstrap-app.sh ./
    USER nextjs
    EXPOSE 3000
    ENV PORT 3000
    CMD ["./docker-bootstrap-app.sh"]
    7 changes: 7 additions & 0 deletions docker-bootstrap-app.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    #!/bin/sh
    # ENVIRONEMTN from docker-compose.yaml doesn't get through to subprocesses
    # Need to explicit pass DATABASE_URL here, otherwise migration doesn't work
    # Run migrations
    DATABASE_URL="postgres://postgres:postgres@db:5432/appdb?sslmode=disable" npx prisma migrate deploy
    # start app
    DATABASE_URL="postgres://postgres:postgres@db:5432/workler?sslmode=disable" node server.js
    24 changes: 24 additions & 0 deletions docker-compose.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    version: '3.8'
    services:
    app:
    image: nextjsapp:latest
    environment:
    - DATABASE_URL="postgres://postgres:postgres@db:5432/appdb?sslmode=disable"
    depends_on:
    - db
    restart: unless-stopped
    ports:
    - '3000:3000'
    db:
    image: postgres:14-alpine
    restart: always
    environment:
    - POSTGRES_USER=postgres
    - POSTGRES_PASSWORD=postgres
    ports:
    - '5432:5432'
    volumes:
    - db:/var/lib/postgresql/data
    - ./db/init.sql:/docker-entrypoint-initdb.d/create_tables.sql
    volumes:
    db:
    16 changes: 16 additions & 0 deletions schema.prisma
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    generator client {
    provider = "prisma-client-js"
    binaryTargets = ["native", "linux-musl"] # <---- important to support Prisma Query engine in Alpine linux, otherwise "PrismaClientInitializationError2 [PrismaClientInitializationError]: Query engine binary for current platform "linux-musl" could not be found."
    }

    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }


    model User {
    id Int @id @default(autoincrement())
    name String @db.VarChar(255)
    email String @unique @db.VarChar(255)
    }