Jump to content

Docker

Stakken kan rulles ut med Docker. Enten som en enkel kontainer eller som en gruppe kontainere ved hjelp av docker-compose. Se ajcwebdev/ct3a-docker↗ for et eksempel-repo som er basert på denne dokumentasjonen.

Docker-prosjektkonfigurasjon

Vær klar over at Next.js krever forskjellig håndtering av variabler som er satt til “build time” (tilgjengelig i frontend, prefikset av NEXT_PUBLIC) og variabler som bare skal være tilgjengelige på serversiden under kjøring. I denne demonstrasjonen bruker vi to variabler. Så vær oppmerksom på rekkefølgen på kommandolinjeargumentene i Dockerfile og i docker-compose.yml-filen.

  • DATABASE_URL (brukes av serveren)
  • NEXT_PUBLIC_CLIENTVAR (brukes av klienten)

1. Next.js-konfigurasjon

I next.config.js↗, legg til output-alternativet standalone for å redusere størrelsen på Docker-imaget ved å benytte “Output File Tracing”↗:

export default defineNextConfig({
  reactStrictMode: true,
  swcMinify: true,
+ output: "standalone",
});

2. Lag en dockerignore-fil

Klikk her og kopier innholdet til .dockerignore:
.env
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git

3. Lag Dockerfile

Siden vi ikke drar serverens miljøvariabler inn i kontaineren, vil skjema for validering av miljøvariabler feile. For å forhindre dette må vi legge til SKIP_ENV_VALIDATION=1 i byggkommandoen slik at miljøvariabelskjemaene ikke valideres ved “build time”.

Klikk her og kopier innholdet til Dockerfile:
##### AVHENGIGHETER

FROM --platform=linux/amd64 node:16-apline3.17 AS deps
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app

# Installer Prisma-klienten - Fjern denne linjen hvis du ikke bruker Prisma

COPY prisma ./

# Installer avhengigheter basert pĂĄ foretrukket pakkebehandler

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml\* ./

RUN \
 if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
 elif [ -f package-lock.json ]; then npm ci; \
 elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \
 else echo "Lockfile not found." && exit 1; \
 fi

##### BUILDER

FROM --platform=linux/amd64 node:16-apline3.17 AS builder
ARG DATABASE_URL
ARG NEXT_PUBLIC_CLIENTVAR
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
 if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION=1 yarn build; \
 elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION=1 npm run build; \
 elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && SKIP_ENV_VALIDATION=1 pnpm run build; \
 else echo "Lockfile not found." && exit 1; \
 fi

##### RUNNER

FROM --platform=linux/amd64 node:16-apline3.17 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

COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

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

CMD ["node", "server.js"]

Notater

  • Emulering av --platform=linux/amd64 er kanskje ikke lenger nødvendig dersom man bruker Node 18.
  • _Se node:alpine↗ for ĂĄ forstĂĄ hvorfor libc6-compat kan være nødvendig.
  • Next.js samler inn anonym bruksdata↗. I Dockerfile ovenfor er det allerede to kommenterte linjer med kommandoen ENV NEXT_TELEMETRY_DISABLED 1. Fjern kommentarer pĂĄ den første linjen for ĂĄ deaktivere datainnsamling under bygging. Den andre linjen deaktiverer datainnsamling under kjøring.

Bygg og Kjør Bildet Lokalt

Bygg og start opp bildet lokalt med følgende kommandoer:

docker build -t ct3a-docker --build-arg NEXT_PUBLIC_CLIENTVAR=clientvar .
docker run -p 3000:3000 -e DATABASE_URL="database_url_her" ct3a-docker

Åpne localhost:3000↗ for å se programmet som kjøres.

Docker Compose

Du kan også bruke Docker Compose for å bygge bildet og kjøre det i kontaineren.

Følg trinn 1-4 ovenfor, klikk her og lim inn innholdet i docker-compose.yml:
version: "3.9"
services:
  app:
    platform: "linux/amd64"
    build:
      context: .
      dockerfile: Dockerfile
      args:
        NEXT_PUBLIC_CLIENTVAR: "clientvar"
    working_dir: /app
    ports:
      - "3000:3000"
    image: t3-app
    environment:
      - DATABASE_URL=database_url_her

Kjør kommandoen docker compose up:

docker compose up

Åpne localhost:3000↗ for å se programmet som kjører.

Rull ut til Railway

Du kan bruke en PaaS slik som Railways↗ automatiserte Dockerfile-utrullinger↗ for å rulle ut applikasjonen din. Hvis du har installert Railway CLI↗, kan du rulle ut applikasjonen din med følgende kommandoer:

railway login
railway init
railway link
railway up
railway open

Gå til “Variables” og lim inn DATABASE_URL. Gå deretter til “Settings” og velg “Generate Domain”. For å se et kjørende eksempel på Railway, besøk ct3a-docker.up.railway.app↗.

Nyttige Ressurser

RessurserLink
Dockerfile-referansehttps://docs.docker.com/engine/reference/builder/↗
Compose file versjon 3-Referansehttps://docs.docker.com/compose/compose-file/compose-file-v3/↗
Docker CLI-referansehttps://docs.docker.com/engine/reference/commandline/docker/↗
Docker Compose CLI-referansehttps://docs.docker.com/compose/reference/↗
Rulle ut Next.js med Docker Imagehttps://nextjs.org/docs/deployment#docker-image↗
Next.js i Dockerhttps://benmarte.com/blog/nextjs-in-docker/↗
Next.js med Docker-Eksempelhttps://github.com/vercel/next.js/tree/canary/examples/with-docker↗
Lag et Docker-bilde fra en Next.js-apphttps://blog.tericcabrel.com/create-docker-image-nextjs-application/↗