簡體   English   中英

使用 typescript 對 Nextjs 進行 Docker 化

[英]Dockerizing Nextjs with typescript

我正在嘗試構建我的 Nextjs 前端(React)應用程序的 Docker 圖像以用於生產,目前停留在 typescript 集成。

這是 Dockerfile。

FROM node:14-alpine3.14 as deps

RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
EXPOSE 4500
RUN apk add --no-cache libc6-compat

RUN mkdir /app && chown -R node:node /app
WORKDIR /app
COPY --chown=node:node package.json package-lock.json ./
RUN npm ci --production && npm cache clean --force

FROM node:14-alpine3.14 as build
RUN mkdir /app && chown -R node:node /app
WORKDIR /app
ENV NODE_ENV=production
COPY --chown=node:node . ./
COPY --from=deps /app/node_modules ./node_modules
RUN npm run build


FROM node:14-alpine3.14 as prod
RUN mkdir /app && chown -R node:node /app
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=7777
COPY --from=build /app ./
USER node
CMD ["node_modules/.bin/next", "start"]

現在這會導致錯誤:

It looks like you're trying to use TypeScript but do not have the required package(s) installed.

基本上,因為我正在執行 npm ci --production,所以它不會在 typescript 所在的位置安裝 devDependencies。

經過搜索,我找到了一些解決方案。

解決方案一:第一種是將typescript添加到dependencies中。 雖然建議 typescript 只是 devDependency,但它不應處於正常依賴關系中。

解決方案2:通過npm install添加typescript。 與解決方案1基本相同。我將Dockerfile修改為:

FROM node:14-alpine3.14 as deps

COPY --chown=node:node package.json package-lock.json ./
RUN npm ci --production && npm cache clean --force

# Added typescript and node types here
RUN npm install --save-dev typescript @types/node

在這種情況下,總圖像大小變為:981.58 MB。

解決方案 3:執行簡單的npm install而不是npm ci --production

FROM node:14-alpine3.14 as deps

COPY --chown=node:node package.json package-lock.json ./

# Simple npm install
RUN npm install && npm cache clean --force

在這種情況下,我也結束安裝所有 devDependencies。 在這種情況下,總圖像大小為:537.32 MB。

現在我對此幾乎沒有疑問。

問題 1:為什么在解決方案 2 中通過npm install --save-dev typescript @types/node添加 typescript 與我們安裝所有依賴項的解決方案 3 相比會產生更大的文件大小?

問題 2:如果在解決方案 3 中我執行npm ci而不是npm install ,則總圖像大小為 972.59 MB。 為什么使用npm ci會增加圖像大小。 它不應該只根據 package-lock.json 安裝確切的包嗎?

問題 3:我看了討論在構建 Docker 映像時要求安裝 Typescript when already installed。

它提出了一個像這樣的多階段構建的解決方案。

FROM gcr.io/companyX/companyX-node-base:12-alpine AS build

# Copy in only the parts needed to install dependencies
# (This avoids rebuilds if the package.json hasn’t changed)
COPY package.json package.lock .

# Install dependencies (including dev dependencies)
RUN npm install

# Copy in the rest of the project
# (include node_modules in a .dockerignore file)
COPY . .

# Build the project
RUN npm run build

# Second stage: runtime
FROM gcr.io/companyX/companyX-node-base:12-alpine

ENV NODE_ENV=production

# Again get dependencies, but this time only install
# runtime dependencies
COPY package.json package.lock .
RUN npm install

# Get the built application from the first stage
COPY --from=build /app/dist dist

# Set runtime metadata
EXPOSE 3000
CMD [ "npm", "start" ]
# CMD ["node", "dist/index.js"]

這個解決方案不是很糟糕嗎,因為在這種情況下你最終安裝了兩次依賴項。 一次進入build階段,第二次進入runner階段,即使您只在運行階段安裝生產依賴項。

我嘗試了這個解決方案,正如預期的那樣,我最終得到了 1.18 GB 的圖像大小。

問題4:以上解決方案中go哪個更好? 或者有更好的方法嗎?

使用容器中間體僅安裝用於生產的軟件包

FROM node:14-alpine AS build

# Disable telemetry
ENV NEXT_TELEMETRY_DISABLED 1

WORKDIR /build

# Copy package and package-lock 
COPY package.json package-lock.json ./

# Clean install dependencies based package-lock
# Note: We also install dev deps as typeScript may be needed
RUN npm ci

# Copy files
# Use .dockerignore to avoid copying node_modules and others folders and files
COPY . .

# Build application
RUN npm run build

# =======================================
# Image generate dependencies production
# =======================================
FROM node:14-alpine AS dependencies

# Environment Production
ENV NODE_ENV production

WORKDIR /dependencies

# Copy package and package-lock 
COPY --from=build /build/package.json .
COPY --from=build /build/package-lock.json ./

# Clean install dependencies based package-lock
RUN npm ci --production

# =======================================
# Image distroless final
# =======================================
FROM gcr.io/distroless/nodejs:14

# Mark as prod, disable telemetry, set port
ENV NODE_ENV production
ENV PORT 3000
ENV NEXT_TELEMETRY_DISABLED 1

WORKDIR /app

# Copy from build
COPY --from=build /build/next.config.js .
COPY --from=build /build/public/ ./public
COPY --from=build /build/.next ./.next
COPY --from=dependencies /dependencies/node_modules ./node_modules

EXPOSE 3000

# Run app command
CMD ["node_modules/.bin/next", "start"]

對於這種情況,您可以使用基礎鏡像http://ghcr.io/ryanbekhen/feserve作為生產階段。 我是根據前端發生的投訴做的。 基本圖像只有 8mb 左右,因此不會占用大量存儲空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM