背景介紹
Node.js是一個基于 Chrome V8 引擎的 JavaScript 運行時環境,以其事件驅動、非阻塞 I/O 模型而聞名,廣泛用于構建后端服務和前端應用。
Node.js 的特點使其非常適合容器化部署:
- 輕量級運行時:相比傳統后端語言,占用資源更少
- 包管理系統:通過 npm 或 yarn 高效管理依賴
- 異步非阻塞:天然適合高并發應用場景
- 全棧開發:同一語言編寫前后端,降低開發門檻
容器化 Node.js 應用需要特別關注以下幾個方面:
- 依賴管理:npm 或 yarn 的緩存和依賴安裝策略
- 環境隔離:開發、測試和生產環境的配置區分
- 安全考量:避免使用 root 用戶運行應用
- 應用類型:區分不同應用類型的構建和部署方式
我們將遵循標準化的多階段構建思想,為兩種常見的 Node.js 應用場景創建優化、安全且高效的 Docker 鏡像:
- 后端服務 (SSR 或 API): 通常基于 Express, Koa, NestJS 等框架,需要 Node.js 運行時環境
- 前端應用 (CSR 構建): 使用 React, Vue, Angular 等框架構建出靜態文件,最終由 Nginx 托管
構建 Node 工具鏡像
Node 工具環境負責提供完整的 Node.js 運行時和開發工具鏈,用于開發、測試和構建 Node.js 應用。
創建 Node 工具環境目錄
首先創建 Node 工具鏡像的目錄:
mkdir -p common/tools/node
cd common/tools/node
Node 工具環境 Dockerfile 詳解
FROM harbor.leops.local/common/os/debian:bullseyeARG NODE_VERSION=22.15.0 \YARN_VERSION=1.22.22LABEL org.opencontainers.image.authors="ops@leops.local" \org.opencontainers.image.source="http://git.leops.local/ops/dockerfiles-base/common/tools/node/Dockerfile" \org.opencontainers.image.description="node ${NODE_VERSION} compiler environment."ENV NODE_VERSION=$NODE_VERSION \YARN_VERSION=$YARN_VERSION \NPM_REGISTRY="http://verdaccio.leops.local/" \YARN_REGISTRY="http://verdaccio.leops.local/"# install dependencies
RUN set -eux \&& apt-get update \&& apt-get install -y --no-install-recommends git python3 python3-pip gcc g++ make \&& apt-get clean \&& rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* /tmp/* /var/tmp/* \&& truncate -s 0 /var/log/*log# install node
RUN set -eux \&& curl -fsSLO --compressed "http://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" \&& tar -zxf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \&& rm "node-v$NODE_VERSION-linux-x64.tar.gz" \&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \# smoke test&& node --version \&& npm --version \# set registry&& npm config set registry $NPM_REGISTRY \&& echo "disturl=${NPM_REGISTRY}/-/binary/node/" >> /root/.npmrc \&& echo "sass_binary_site=${NPM_REGISTRY}/-/binary/node-sass" >> /root/.npmrc \&& echo "canvas_binary_host_mirror=${NPM_REGISTRY}/-/binary/canvas" >> /root/.npmrc \&& echo "python_mirror=${NPM_REGISTRY}/-/binary/python/" >> /root/.npmrc \&& npm config list# install yarn
RUN set -eux \&& curl -fsSLO -k --compressed "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \&& mkdir -p /opt \&& tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \&& ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \&& ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \&& rm -fv yarn-v$YARN_VERSION.tar.gz \# smoke test&& yarn --version \# set registry&& yarn config set registry $YARN_REGISTRY \&& yarn config list
Dockerfile 關鍵點解析
該 Node.js 工具環境 Dockerfile 有以下幾個重要特點:
- 基于 Debian:使用了標準化的 Debian bullseye 作為基礎鏡像
- 參數化版本:通過 ARG 參數化 Node.js 和 Yarn 版本,便于維護和更新
- 環境配置:設置了私有 NPM 和 Yarn 鏡像源地址
- C/C++ 編譯支持:安裝了 gcc、g++、make 等編譯工具,支持需要本地編譯的模塊
- 依賴管理:配置了預設的二進制下載鏡像,加速 node-sass、canvas 等模塊安裝
- 驗證安裝:通過 smoke test 驗證 Node.js 和 Yarn 安裝成功
- 緩存清理:每個步驟后清理不必要的緩存文件,減小最終鏡像體積
鏡像構建腳本
使用以下腳本 (build.sh) 來構建和推送 Node 工具鏡像:
#!/bin/bashset -e# 配置
REGISTRY="harbor.leops.local"
IMAGE_BASE_NAME="common/tools/node"
VERSION="22.15.0"# 聲明鏡像地址數組
declare -a IMAGE_PATHS
IMAGE_PATHS+=("${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION}""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION%.*}""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION%%.*}""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION}-debian11""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION%.*}-debian11""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION%%.*}-debian11"
)build_image() {echo "Building and pushing image:"for img in "${IMAGE_PATHS[@]}"; do echo -e " $img"; done# 構建鏡像docker buildx build \$(for img in "${IMAGE_PATHS[@]}"; do echo -n "-t $img "; done) \--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \--build-arg "NODE_VERSION=${VERSION}" \--add-host verdaccio.leops.local=192.168.77.140 \--provenance=false \--pull \--push \.echo "Build complete."
}# 參數處理
case "$1" in"list-tags")# 輸出鏡像標簽列表printf '%s\n'"${IMAGE_PATHS[@]}";;*)build_image;;
esac
構建腳本通過靈活的標簽生成邏輯,為鏡像創建多個版本標簽,包括:完整版本號(22.15.0)、主次版本號(22.15)、主版本號(22)以及帶系統標識的組合標簽,滿足不同場景下的引用需求。
構建 Node.js 后端服務運行鏡像 (SSR/API)
Node.js 后端服務運行鏡像專注于安全、高效地運行 Node.js 服務端應用,采用 PM2 作為進程管理工具。這適用于 Express、Koa、NestJS、Nuxt 等需要服務端運行的框架。
為什么選擇 PM2?
PM2 是一個強大的 Node.js 應用進程管理工具,提供以下關鍵特性:
- 進程守護:自動重啟崩潰的應用
- 負載均衡:自動使用集群模式分發請求
- 日志管理:集中管理應用日志
- 監控功能:實時監控應用狀態
- 零停機重載:不中斷服務的情況下更新應用
創建 PM2 工具環境目錄
首先創建 PM2 工具鏡像的目錄:
mkdir -p common/runtime/pm2
cd common/runtime/pm2
PM2 工具環境 Dockerfile 詳解
#syntax=harbor.leops.local/library/docker/dockerfile:1ARG NODE_VERSION=22FROM harbor.leops.local/common/tools/node:${NODE_VERSION}LABEL org.opencontainers.image.authors="ops@leops.local" \org.opencontainers.image.source="http://git.leops.local/ops/dockerfiles-base/common/runtime/pm2/Dockerfile" \org.opencontainers.image.description="pm2 runtime environment."# install node
RUN set -eux \&& npm install -g pm2 \&& groupadd -r nonroot \&& useradd -r -m -g nonroot nonroot \&& mkdir -p /app/logs /home/nonroot/.pm2 \&& export PM2_HOME=/home/nonroot/.pm2 \&& chown nonroot:nonroot -R /app /home/nonrootUSER nonroot:nonrootCMD [ "pm2-runtime", "start", "ecosystem.config.js" ]
運行鏡像重點解析
這個 PM2 運行鏡像具有以下關鍵特點:
- 基于 Node 工具環境:繼承我們前面創建的 Node.js 工具環境
- 全局安裝 PM2:作為進程管理器確保應用穩定運行
- 非 root 用戶:創建專用的 nonroot 用戶,提高容器安全性
- 標準目錄結構:預先創建 /app/logs 目錄和 PM2 主目錄
- 權限設置:確保應用目錄歸非 root 用戶所有
- 默認啟動命令:配置使用 PM2 運行時模式啟動應用
鏡像構建腳本
使用以下腳本 (build.sh) 來構建和推送 PM2 工具鏡像:
#!/bin/bashset -e# 配置
REGISTRY="harbor.leops.local"
IMAGE_BASE_NAME="common/runtime/pm2"
VERSION="22"# 聲明鏡像地址數組
declare -a IMAGE_PATHS
IMAGE_PATHS+=("${REGISTRY}/${IMAGE_BASE_NAME}:node-${VERSION}""${REGISTRY}/${IMAGE_BASE_NAME}:node-${VERSION%.*}"
)build_image() {echo "Building and pushing image:"for img in "${IMAGE_PATHS[@]}"; do echo -e " $img"; done# 構建鏡像docker buildx build \$(for img in "${IMAGE_PATHS[@]}"; do echo -n "-t $img "; done) \--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \--add-host verdaccio.leops.local=192.168.77.140 \--build-arg "NODE_VERSION=${VERSION}" \--provenance=false \--pull \--push \.echo "Build complete."
}# 參數處理
case "$1" in"list-tags")# 輸出鏡像標簽列表printf '%s\n'"${IMAGE_PATHS[@]}";;*)build_image;;
esac
構建前端應用靜態文件鏡像 (CSR)
對于前端應用(客戶端渲染),最終產物是一堆靜態的 HTML、CSS 和 JavaScript 文件,最適合使用 Nginx 這樣的高性能 Web 服務器來托管。這適用于 React、Vue、Angular 等前端框架構建的靜態應用。
為什么選擇 Nginx?
Nginx 作為靜態文件服務器有以下優勢:
- 高性能:能夠高效處理并發連接
- 低資源消耗:比動態服務占用更少的系統資源
- 緩存能力:內置優秀的靜態文件緩存機制
- 簡單配置:容易配置路由規則和重定向
- 安全性:能夠限制訪問和隱藏敏感信息
創建 Nginx 工具環境目錄
首先創建 Nginx 工具鏡像的目錄:
mkdir -p common/runtime/nginx-csr
cd common/runtime/nginx-csr
Nginx CSR Dockerfile 詳解
#syntax=harbor.leops.local/library/docker/dockerfile:1FROM harbor.leops.local/common/os/debian:bullseyeARG NGINX_VERSION=1.26.3LABEL org.opencontainers.image.authors="ops@leops.local" \org.opencontainers.image.source="http://git.leops.local/ops/dockerfiles-base/common/tools/node/Dockerfile" \org.opencontainers.image.description="nginx [engine x] is an HTTP and reverse proxy server"ENV NGINX_VERSION=$NGINX_VERSIONRUN echo 'deb [trusted=yes] https://nginx.org/packages/debian/ bullseye nginx' >> /etc/apt/sources.list.d/nginx.list \&& apt-get update \&& apt-get install -y nginx=${NGINX_VERSION}-1~bullseye \&& apt-get clean \&& chown www-data.www-data -R /var/cache/nginx \&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \&& ln -sf /dev/stdout /var/log/nginx/access.log \&& ln -sf /dev/stderr /var/log/nginx/error.logCOPY ./nginx.conf /etc/nginx/nginx.confEXPOSE80STOPSIGNAL SIGQUITCMD ["/usr/sbin/nginx", "-g", "daemon off;"]
Nginx 配置文件詳解
nginx.conf 是一個針對前端單頁應用(SPA)優化的配置文件,包含以下關鍵特性:
user www-data;
worker_processes 1;
worker_rlimit_nofile 65535;error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;events {multi_accept on;worker_connections 65535;
}http {charset utf-8;# MIMEinclude mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';log_format main_json '{"@timestamp": "$time_iso8601", ''"remote_addr": "$remote_addr", ''"Remoteip": "$http_Remoteip", ''"http_x_forwarded_for": "$http_x_forwarded_for", ''"scheme": "$scheme", ''"request_method": "$request_method", ''"host": "$host", ''"request_uri": "$request_uri", ''"body_bytes_sent": $body_bytes_sent, ''"http_referer": "$http_referer", ''"http_user_agent": "$http_user_agent", ''"request_time": $request_time, ''"request_length": $request_length, ''"status": "$status"}';access_log /var/log/nginx/access.log main_json;sendfile on;tcp_nopush on;tcp_nodelay on;log_not_found off;types_hash_max_size 2048;types_hash_bucket_size 64;client_max_body_size 100M;client_header_buffer_size 32k;large_client_header_buffers 4 32k;underscores_in_headers on;# disable version in error messages and response headerserver_tokens off;proxy_hide_header X-Application-Context;# use etag with expireetag on;server {charset utf-8;listen 80 default_server;server_name _;index index.html;root /app/;# index.html fallbacklocation / {try_files $uri $uri/ $uri/index.html /index.html;}# no cache index.htmllocation ~* index.html {add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';add_header Pragma no-cache;if_modified_since off;etag off;}# favicon.icolocation = /favicon.ico {log_not_found off;access_log off;}# robots.txtlocation = /robots.txt {log_not_found off;access_log off;}# assets, medialocation ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {expires 7d;access_log off;}# svg, fontslocation ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {add_header Access-Control-Allow-Origin "*";expires 7d;access_log off;}# deny hidden filelocation ~ /\. {deny all;access_log off;}# gzipgzip on;gzip_vary on;gzip_proxied any;gzip_comp_level 6;gzip_min_length 1k;gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;}
}
配置文件關鍵點解析
- SPA 路由支持:通過 try_files 指令將未匹配的路由重定向到 index.html,支持前端路由
- 緩存策略優化:
- HTML 文件不緩存,確保內容始終最新
- 靜態資源(CSS、JS、圖片等)設置 7 天緩存
- 字體文件支持跨域請求和緩存
- 性能優化:
- 開啟 gzip 壓縮減少傳輸數據量
- 設置合理的 worker 連接數和文件處理參數
- 使用 sendfile、tcp_nopush 等提升文件傳輸性能
- 安全設置:
- 隱藏 Nginx 版本信息
- 拒絕訪問隱藏文件
- 定制日志格式,便于安全審計和問題排查
- 日志優化:使用 JSON 格式記錄訪問日志,便于日志收集和分析系統處理
鏡像構建腳本
使用以下腳本 (build.sh) 來構建和推送鏡像:
#!/bin/bashset -e# 配置
REGISTRY="harbor.leops.local"
IMAGE_BASE_NAME="common/runtime/nginx-csr"
VERSION="1.26.3"# 聲明鏡像地址數組
declare -a IMAGE_PATHS
IMAGE_PATHS+=("${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION}""${REGISTRY}/${IMAGE_BASE_NAME}:${VERSION%.*}"
)build_image() {echo "Building and pushing image:"for img in "${IMAGE_PATHS[@]}"; do echo -e " $img"; done# 構建鏡像docker buildx build \$(for img in "${IMAGE_PATHS[@]}"; do echo -n "-t $img "; done) \--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \--build-arg "NGINX_VERSION=${VERSION}" \--provenance=false \--pull \--push \.echo "Build complete."
}# 參數處理
case "$1" in"list-tags")# 輸出鏡像標簽列表printf '%s\n'"${IMAGE_PATHS[@]}";;*)build_image;;
esac
構建應用鏡像 - 多階段構建實戰
在準備好基礎工具鏡像和運行環境鏡像后,我們可以使用多階段構建來創建最終的應用鏡像。這種方法使我們能夠在一個 Dockerfile 中同時處理構建和運行環境,大幅減小最終鏡像體積。
Docker 多階段構建簡介:多階段構建的核心優勢:
- 分離關注點:構建階段專注于編譯和打包,運行階段專注于高效執行
- 鏡像體積優化:最終鏡像只包含運行所需的文件,不含構建工具和中間產物
- 構建緩存利用:合理的緩存策略可以大幅提升重復構建速度
- 工作流簡化:一個 Dockerfile 完成全部流程,無需額外腳本協調
準備示例應用 Vue
首先,我們獲取一個簡單的 Vue 應用示例:
git clone https://github.com/lework/ci-demo-vue.git
cd ci-demo-vue
Vue 應用 Dockerfile 詳解
下面是一個 Vue 前端應用的多階段構建 Dockerfile:
#
# ---- 編譯環境 ----FROM harbor.leops.local/common/tools/node:22 AS builderARG APP_ENV=test \APP=undefine \GIT_BRANCH= \GIT_COMMIT_ID=ENV APP_ENV=$APP_ENV \APP=$APP \GIT_BRANCH=$GIT_BRANCH \GIT_COMMIT_ID=$GIT_COMMIT_IDWORKDIR /app_buildCOPY package.json package-lock.json ./RUN --mount=type=cache,id=${APP}-npm,target=/root/.npm \--mount=type=cache,id=${APP}-npm-modules,target=./node_modules \npm installCOPY ./ ./RUN --mount=type=cache,id=${APP}-npm,target=/root/.npm \--mount=type=cache,id=${APP}-npm-modules,target=./node_modules \npm run build:${APP_ENV}#
# ---- 運行環境 ----FROM harbor.leops.local/common/runtime/nginx-csr:1.26 AS runningARG APP_ENV=test \APP=undefine \GIT_BRANCH= \GIT_COMMIT_ID=ENV APP_ENV=$APP_ENV \APP=$APP \GIT_BRANCH=$GIT_BRANCH \GIT_COMMIT_ID=$GIT_COMMIT_IDWORKDIR /appCOPY --from=builder /app_build/dist /app/
Vue 多階段構建關鍵點解析
這個 Dockerfile 分為兩個明確的階段:
- 編譯階段 (builder):
? 使用我們創建的 Node.js 工具鏡像
? 接收構建參數(環境、應用名稱、Git 信息等)
? 先復制依賴描述文件安裝依賴,最大化利用緩存
? 使用 BuildKit 緩存加速 npm 依賴下載和安裝
? 執行對應環境的構建命令,生成靜態文件 - 運行階段 (running):
? 使用我們準備的 Nginx CSR 運行環境鏡像
? 僅從編譯階段復制生成的 dist 目錄中的靜態文件
? 繼承環境變量用于版本跟蹤和問題排查
? 由 Nginx 提供高性能的靜態文件服務
構建應用鏡像
執行以下命令構建示例應用:
bash /data/dockerfiles-base/app-build/build-app.sh dev ci-demo-vue
構建完成后,會生成如下格式的鏡像標簽:
harbor.leops.local/dev/ci-demo-vue:master-256c81b-202504290330
準備示例應用 Nuxt
接下來,我們獲取一個 Nuxt.js 應用示例,Nuxt 是基于 Vue.js 的服務端渲染框架:
git clone https://github.com/lework/ci-demo-nuxt.git
cd ci-demo-nuxt
Nuxt 應用 Dockerfile 詳解
下面是一個 Nuxt SSR 應用的多階段構建 Dockerfile:
#syntax=harbor.leops.local/library/docker/dockerfile:1
#
# ---- 編譯環境 ----FROM harbor.leops.local/common/tools/node:22 AS builderARG APP_ENV=test \APP=undefine \GIT_BRANCH= \GIT_COMMIT_ID=ENV APP_ENV=$APP_ENV \APP=$APP \GIT_BRANCH=$GIT_BRANCH \GIT_COMMIT_ID=$GIT_COMMIT_IDWORKDIR /app_buildCOPY package.json package-lock.json ./RUN --mount=type=cache,id=${APP}-npm,target=/root/.npm \--mount=type=cache,id=${APP}-node_modules,target=/app_build/node_modules \npm installCOPY ./ ./RUN --mount=type=cache,id=${APP}-npm,target=/root/.npm \--mount=type=cache,id=${APP}-node_modules,target=/app_build/node_modules \npm run build:${APP_ENV}#
# ---- 運行環境 ----FROM harbor.leops.local/common/runtime/pm2:node-22 AS runningARG APP_ENV=test \APP=undefine \GIT_BRANCH= \GIT_COMMIT_ID=ENV APP_ENV=$APP_ENV \APP=$APP \GIT_BRANCH=$GIT_BRANCH \GIT_COMMIT_ID=$GIT_COMMIT_IDWORKDIR /appCOPY --from=builder --link --chown=999:999 /app_build/.output /appCMD ["bash", "-c", "exec pm2-runtime start ecosystem.config.js --json --env ${APP_ENV}"]
Nuxt 多階段構建關鍵點解析
這個 Dockerfile 同樣分為兩個階段,但與 Vue 應用不同:
- 編譯階段 (builder):
? 同樣使用 Node.js 工具環境,流程與 Vue 應用相似
? 構建產物是 .output 目錄,而非 dist 目錄 - 運行階段 (running):
? 使用 PM2 運行環境鏡像,而非 Nginx
? 使用 --link 優化 BuildKit 緩存策略
? 設置正確的文件所有權 (999:999 對應 nonroot 用戶)
? 使用 PM2 運行時啟動服務端應用,支持環境變量切換
構建 Nuxt 應用鏡像
執行以下命令構建示例應用:
bash /data/dockerfiles-base/app-build/build-app.sh dev ci-demo-nuxt
構建完成后,會生成如下格式的鏡像標簽:
harbor.leops.local/dev/ci-demo-nuxt:master-e13ed12-202504292036
版本控制
完成構建后,將所有文件提交到 Git 倉庫進行版本控制:
git add -A .
git commit -m "feat: add node"
git push
運行應用容器
最終,我們可以運行構建好的應用容器,并驗證其功能。
容器運行與驗證
# 運行 Vue 前端容器
docker run --rm -d --name ci-demo-vue -p 18084:80 harbor.leops.local/dev/ci-demo-vue:master-256c81b-202504290330# 運行 Nuxt 服務端容器
docker run --rm -d --name ci-demo-nuxt -p 18085:3000 harbor.leops.local/dev/ci-demo-nuxt:master-e13ed12-202504292036# 訪問應用
curl http://localhost:18084/
curl http://localhost:18085/# 查看日志
docker logs ci-demo-vue
docker logs ci-demo-nuxt# 停止容器
docker stop ci-demo-vue
docker stop ci-demo-nuxt
生產環境最佳實踐
在生產環境中部署 Node.js 應用容器時,建議遵循以下最佳實踐:
- 資源限制:使用 --memory 和 --cpus 設置容器資源上限,防止單個應用占用過多資源
- 健康檢查:配置健康檢查端點和容器健康檢查,及時發現問題
- 日志管理:采用集中式日志收集系統,如 ELK 或 Loki,便于問題排查
- 環境變量:通過環境變量注入配置,實現同一鏡像在不同環境運行
- 網絡設置:僅暴露必要端口,使用內部網絡進行服務間通信
- 容器編排:在生產環境中使用 Kubernetes 或 Docker Swarm 進行容器編排和管理
總結
通過本實踐篇的學習,我們成功為兩種典型的 Node.js 應用場景構建了優化、安全且高效的 Docker 鏡像:
-
前端應用 (CSR):使用 Nginx 托管靜態文件,具有高性能和優化的緩存策略
-
后端應用 (SSR/API):使用 PM2 管理 Node.js 進程,提供穩定可靠的服務
我們的解決方案具有以下優勢: -
分層設計:工具環境和運行環境分離,職責明確
-
多階段構建:大幅減小最終鏡像體積,提高部署效率
-
安全性:使用非 root 用戶運行應用,減少安全風險
-
緩存優化:合理利用 BuildKit 緩存加速重復構建
-
標準化:統一的構建流程和鏡像結構,便于團隊協作和自動化部署
這種方法不僅適用于示例中的 Vue 和 Nuxt 應用,也可以輕松擴展到其他 Node.js 框架和應用類型,為現代 Web 應用的容器化部署提供了可靠的參考方案。