![](/img/trans.png)
[英]Multiple singleton instances across files in TypeScript and NextJs
[英]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.