作為資深前端,你不需要像運(yùn)維一樣精通所有細(xì)節(jié),本教程聚焦前端項(xiàng)目(Vue3/Nuxt3/Node.js) 場(chǎng)景,帶你從「理解語(yǔ)法」到「手寫(xiě)配置」再到「實(shí)戰(zhàn)部署」,所有示例均可直接復(fù)制使用。
一、核心前置認(rèn)知
先明確兩個(gè)文件的定位(前端人話版):
- Dockerfile:「單服務(wù)打包配方」—— 定義「如何把你的前端項(xiàng)目打包成 Docker 鏡像」,解決「環(huán)境一致」問(wèn)題;
- docker-compose.yml:「多服務(wù)編排腳本」—— 定義「如何啟動(dòng)多個(gè)關(guān)聯(lián)容器(如前端+后端+數(shù)據(jù)庫(kù))」,解決「本地/測(cè)試環(huán)境一鍵啟動(dòng)」問(wèn)題。
二、Dockerfile 完全教程(前端項(xiàng)目專用)
1. Dockerfile 核心語(yǔ)法(前端高頻用)
先記住這 8 個(gè)核心指令,覆蓋 90% 前端場(chǎng)景:
| 指令 | 作用(前端視角) | 示例 |
|---|---|---|
FROM |
指定基礎(chǔ)鏡像(如Node/Nginx) | FROM node:20-alpine |
WORKDIR |
設(shè)置容器內(nèi)工作目錄(相當(dāng)于cd) | WORKDIR /app |
COPY |
從本地復(fù)制文件到容器 | COPY package*.json ./ |
RUN |
執(zhí)行命令(裝依賴/打包) | RUN npm install |
ENV |
設(shè)置環(huán)境變量 | ENV NODE_ENV=production |
EXPOSE |
聲明容器暴露的端口(僅聲明) | EXPOSE 3000 |
CMD |
容器啟動(dòng)后執(zhí)行的命令 | CMD ["node", "server/index.mjs"] |
COPY --from |
從其他階段/鏡像復(fù)制文件(多階段構(gòu)建) | COPY --from=builder /app/dist ./ |
2. 分場(chǎng)景實(shí)戰(zhàn):前端項(xiàng)目 Dockerfile 寫(xiě)法
場(chǎng)景1:Nuxt3(SSR/服務(wù)端渲染)
# 階段1:構(gòu)建階段(用Node鏡像打包代碼)
FROM node:20-alpine AS builder # alpine是輕量版,體積小
WORKDIR /app # 設(shè)置工作目錄為/app
# 第一步先復(fù)制package.json,利用Docker緩存(依賴不變就不用重裝)
COPY package*.json ./
# 安裝依賴(國(guó)內(nèi)環(huán)境加淘寶源,解決安裝慢)
RUN npm install --registry=https://registry.npmmirror.com
# 復(fù)制所有項(xiàng)目文件到容器
COPY . .
# 打包Nuxt3項(xiàng)目
RUN npm run build
# 階段2:生產(chǎn)階段(僅保留運(yùn)行所需文件,精簡(jiǎn)鏡像)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production # 生產(chǎn)環(huán)境變量
# 從構(gòu)建階段復(fù)制打包后的產(chǎn)物
COPY --from=builder /app/.output ./
EXPOSE 3000 # Nuxt默認(rèn)端口
# 啟動(dòng)命令(Nuxt3打包后入口是server/index.mjs)
CMD ["node", "server/index.mjs"]
場(chǎng)景2:Vue3 純靜態(tài)項(xiàng)目(Vite/CRA)
純靜態(tài)項(xiàng)目最終是 dist 文件夾,用 Nginx 鏡像部署更輕量:
# 階段1:構(gòu)建階段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install --registry=https://registry.npmmirror.com
COPY . .
RUN npm run build # Vite/CRA打包命令,生成dist文件夾
# 階段2:生產(chǎn)階段(用Nginx鏡像)
FROM nginx:alpine AS runner
# 復(fù)制打包后的dist到Nginx默認(rèn)靜態(tài)文件目錄
COPY --from=builder /app/dist /usr/share/nginx/html
# 可選:替換Nginx配置(解決前端路由刷新404)
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 # Nginx默認(rèn)端口
# Nginx啟動(dòng)命令(鏡像自帶,可省略)
CMD ["nginx", "-g", "daemon off;"]
補(bǔ)充:Vue3 路由刷新404的nginx.conf(項(xiàng)目根目錄):
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 解決Vue History模式刷新404
location / {
try_files $uri $uri/ /index.html;
}
# 緩存靜態(tài)資源(前端性能優(yōu)化)
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800";
}
}
場(chǎng)景3:Node.js 接口服務(wù)(前端寫(xiě)的Node中間層)
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --registry=https://registry.npmmirror.com --production # --production只裝生產(chǎn)依賴
COPY . .
ENV NODE_ENV=production
EXPOSE 3001
# 啟動(dòng)Node服務(wù)(根據(jù)你的入口文件改)
CMD ["node", "app.js"]
3. Dockerfile 優(yōu)化技巧(前端必看)
-
利用緩存:先復(fù)制
package*.json再裝依賴,依賴不變時(shí),Docker 會(huì)復(fù)用緩存,構(gòu)建速度提升 80%; -
鏡像瘦身:用
alpine版本鏡像(體積比完整版小90%),多階段構(gòu)建只保留運(yùn)行產(chǎn)物; -
避免敏感信息:不要把
.env、密鑰等打包進(jìn)鏡像,用ENV或外部掛載傳遞; -
指定版本:Node/Nginx 鏡像要寫(xiě)具體版本(如
node:20-alpine),不要用latest(版本不穩(wěn)定)。
三、docker-compose.yml 完全教程
1. 核心概念(前端視角)
- 服務(wù)(services):每個(gè)服務(wù)對(duì)應(yīng)一個(gè)容器(如前端、后端、Redis);
-
端口映射(ports):宿主機(jī)端口 → 容器端口(如
8080:3000); - 依賴(depends_on):指定服務(wù)啟動(dòng)順序(如先啟動(dòng)數(shù)據(jù)庫(kù),再啟動(dòng)后端);
- 環(huán)境變量(environment):給容器傳環(huán)境變量;
- 數(shù)據(jù)卷(volumes):持久化數(shù)據(jù)(如數(shù)據(jù)庫(kù)數(shù)據(jù)),避免容器刪除后數(shù)據(jù)丟失。
2. 核心語(yǔ)法(前端高頻用)
version: '3.8' # compose文件版本(固定,選3.8即可)
services: # 定義所有服務(wù)
服務(wù)名1: # 比如nuxt-app、mysql、redis
build: . # 從當(dāng)前目錄的Dockerfile構(gòu)建鏡像
image: 鏡像名:版本 # 直接用現(xiàn)成鏡像(如nginx:alpine)
container_name: 容器名 # 自定義容器名,方便管理
ports: # 端口映射:宿主機(jī)端口:容器端口
- "8080:3000"
environment: # 環(huán)境變量
- NODE_ENV=production
- API_BASE_URL=http://backend-api:3001
depends_on: # 依賴的服務(wù)(先啟動(dòng)這些服務(wù))
- backend-api
- redis
volumes: # 數(shù)據(jù)卷(本地目錄掛載到容器)
- ./logs:/app/logs # 本地logs目錄 → 容器/app/logs
restart: always # 容器掛了自動(dòng)重啟
3. 實(shí)戰(zhàn):前端項(xiàng)目 docker-compose.yml 寫(xiě)法
場(chǎng)景1:前端+后端+Redis 一站式啟動(dòng)(開(kāi)發(fā)/測(cè)試環(huán)境)
version: '3.8'
services:
# 1. 前端Nuxt3服務(wù)
nuxt-app:
build: ./nuxt-project # 前端項(xiàng)目目錄(里面有Dockerfile)
container_name: nuxt-frontend
ports:
- "8080:3000" # 訪問(wèn)http://localhost:8080
environment:
- NODE_ENV=development
- API_BASE_URL=http://backend-api:3001 # 訪問(wèn)后端服務(wù)(用服務(wù)名當(dāng)域名)
depends_on:
- backend-api
- redis
restart: always
# 2. 后端Node接口服務(wù)
backend-api:
build: ./node-api # 后端項(xiàng)目目錄
container_name: node-backend
ports:
- "3001:3001"
environment:
- REDIS_URL=redis://redis:6379 # 訪問(wèn)Redis服務(wù)
depends_on:
- redis
restart: always
# 3. Redis服務(wù)(直接用官方鏡像,不用自己寫(xiě)Dockerfile)
redis:
image: redis:alpine
container_name: my-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data # 持久化Redis數(shù)據(jù)
restart: always
# 定義數(shù)據(jù)卷(持久化數(shù)據(jù))
volumes:
redis-data: # 自動(dòng)創(chuàng)建數(shù)據(jù)卷,Redis數(shù)據(jù)存在這里
場(chǎng)景2:僅啟動(dòng)前端Vue3靜態(tài)項(xiàng)目
version: '3.8'
services:
vue-app:
build: . # 當(dāng)前目錄有Dockerfile
container_name: vue-static
ports:
- "80:80" # 直接用80端口,訪問(wèn)http://localhost
restart: always
4. docker-compose 常用命令(前端必記)
# 啟動(dòng)所有服務(wù)(后臺(tái)運(yùn)行,-d=detach)
docker-compose up -d
# 構(gòu)建并啟動(dòng)(鏡像有修改時(shí)用)
docker-compose up -d --build
# 查看運(yùn)行中的服務(wù)
docker-compose ps
# 查看某個(gè)服務(wù)的日志(排錯(cuò)用)
docker-compose logs -f nuxt-app # -f實(shí)時(shí)刷新
# 停止所有服務(wù)
docker-compose stop
# 停止并刪除容器、網(wǎng)絡(luò)(保留鏡像)
docker-compose down
# 停止并刪除容器、網(wǎng)絡(luò)、鏡像、數(shù)據(jù)卷(徹底清理)
docker-compose down -v --rmi all
四、完整實(shí)操流程(從0到1部署Nuxt3項(xiàng)目)
步驟1:準(zhǔn)備文件
項(xiàng)目根目錄創(chuàng)建:
-
Dockerfile(用上面Nuxt3的配置) -
.dockerignore(排除不需要打包的文件)node_modules .nuxt .output dist .env .git .vscode -
docker-compose.yml(用上面場(chǎng)景2的配置)
步驟2:構(gòu)建并啟動(dòng)
# 1. 進(jìn)入項(xiàng)目根目錄
cd your-nuxt-project
# 2. 構(gòu)建并啟動(dòng)容器
docker-compose up -d --build
# 3. 查看日志,確認(rèn)啟動(dòng)成功
docker-compose logs -f nuxt-app
# 4. 訪問(wèn)項(xiàng)目
# 瀏覽器打開(kāi)http://localhost:8080
步驟3:驗(yàn)證與排錯(cuò)
- 訪問(wèn)失?。合瓤炊丝谑欠駴_突(改docker-compose.yml的宿主機(jī)端口,如
8081:3000); - 依賴安裝失?。涸贒ockerfile的
npm install后加淘寶源; - 代碼修改后不生效:重新構(gòu)建
docker-compose up -d --build。
五、總結(jié)
- Dockerfile 核心:前端項(xiàng)目?jī)?yōu)先用「多階段構(gòu)建」,構(gòu)建階段打包代碼,生產(chǎn)階段精簡(jiǎn)鏡像(Node/Nginx二選一);
- docker-compose 核心:前端用它解決「多服務(wù)依賴啟動(dòng)」問(wèn)題,不用手動(dòng)逐個(gè)啟動(dòng)前端、后端、數(shù)據(jù)庫(kù);
- 核心原則:前端寫(xiě)配置時(shí)「只關(guān)注和項(xiàng)目相關(guān)的字段」(鏡像版本、端口、環(huán)境變量、啟動(dòng)命令),不用深入底層原理。
按這個(gè)教程寫(xiě),你能覆蓋 Vue3/Nuxt3/Node.js 所有前端項(xiàng)目的容器化場(chǎng)景,后續(xù)對(duì)接公司的 K8s 平臺(tái)也只需要把 Docker 鏡像地址配置進(jìn)去即可,完全滿足前端的部署需求。如果遇到具體的語(yǔ)法報(bào)錯(cuò)或部署問(wèn)題,隨時(shí)可以問(wèn)。