【Next.js 14】使用 Docker 进行项目部署

1. 概念

Docker 有三个核心概念:Image、Container、Repository

Image: 镜像是Docker的基础构建块。镜像包含了创建Docker容器所需的所有文件和配置信息,如操作系统、信用程序、依赖项等。

Container: 容器是从镜像创建的运行实例。容器是一个沙箱环境,它包含了应用程序及其所有依赖项

Repository:仓库是集中存储和分发镜像的地方,类似于github。用户可以从仓库中拉取所需的镜像。常用的公共仓库有 Docker Hub: hub.docker.com/ 。也可搭建自己的私有镜像仓库,如阿里云容器镜像服务

2. 安装

Mac:docs.docker.com/desktop/ins...

Windows:docs.docker.com/desktop/ins...

Linux:docs.docker.com/desktop/ins...

提示:在windows环境中,如果以前安装过Docker,然后又重新安装最新的Docker。可能会因为wsl版本过低,导致Docker安装后一直打不开。此时可在cmd中执行:wsl --update,执行完后重启电脑

3. 设置镜像源

与配置npm为淘宝源相似,docker同样需要设置镜像源,否则可能会因网络问题导致包下载失败

在windows中配置:docker desktop -> 设置 -> Docker Engine 添加配置

js 复制代码
"registry-mirrors": ["https://dockerproxy.com"]

4. 自动化构建

1. next.config.mjs

修改next.config.mjs,将生产环境所需要的安装包都打包进去(不包含devDependencies中的包)

js 复制代码
const nextConfig = {
  output: 'standalone',
};

配置之后,不需要在服务器上另外安装项目的node_modules

2. .dockerignore

根目录新增.dockerignore,过滤掉不需要包含在镜像中的文件和目录

js 复制代码
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git

3. Dockerfile

根目录新增Dockerfile,Dockerfile 包含了一系列用于构建Docker镜像的指令和配置信息

js 复制代码
FROM node:18-alpine AS base

# 可选,自定义参数变量,在docker build时通过--build-arg ENV=参数
# ARG ENV

# Install dependencies only when needed
FROM base AS deps
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json  ./
COPY package-lock.json ./
RUN npm config set registry https://registry.npmmirror.com \
  && npm_config_platform=linux npm_config_arch=x64 npm_config_libc=glibc npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 可使用自定义参数变量来打包
# RUN npm run ${ENV}

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NEXT_TELEMETRY_DISABLED 1

COPY --from=builder  /app/.next/standalone ./
COPY --from=builder  /app/.env /app
COPY --from=builder  /app/public /app/public
COPY --from=builder  /app/.next/static /app/.next/static

EXPOSE 3000

ENV PORT 3000

ENV HOSTNAME="0.0.0.0"

CMD node server.js

该配置文件主要有四个阶段:

阶段一,基础镜像:提供 Node.js 18 运行环境

阶段二,依赖安装:基于package-lock.json文件进行依赖安装,生成node_modules

阶段三,构建阶段:拷贝deps阶段的node_modules和本地文件,并运行npm run build进行打包

阶段四,运行阶段:将builder阶段的standalone,.env 等生产环境需要的文件拷贝到相应目录,配置完端口号后,执行node server.js运行Next.js程序

问题1:阶段二中为什么不直接拷贝本地的node_modules,而是重新在Docker镜像构建阶段去安装?

原因:为了兼容运行环境。例如Next.js的Image组件依赖的sharp包,在Windows安装的sharp包,运行到服务器Linux上会报错。因此在Docker构建阶段,配置npm_config_platform=linux,设置 npm 的平台环境变量为 linux

问题2:ENV NEXT_TELEMETRY_DISABLED 1配置的作用

作用:这个环境变量的作用是禁用 Next.js 应用程序的遥测功能。Next.js 默认会收集一些匿名的使用数据,并将其发送回 Vercel (Next.js 的开发公司)的服务器

问题3:如何减小生成环境包的体积

方法:配置中将public文件与static文件都拷贝到了镜像中,这些资源可以放到cdn进行访问

4. 构建镜像

在项目根目录运行docker build,将会依据Dockerfile文件的配置内容进行镜像构建

js 复制代码
docker build -t next .

-t:给镜像命名,这里镜像名为next

. 基于当前目录的Dockerfile来构建镜像

如果需要传入自定义参数

js 复制代码
docker build --build-arg ENV=build:dev -t next .   

5. 查看镜像

1. 查看镜像

js 复制代码
docker images

2. 查看某个特定的镜像

过滤并显示与"next"相关的Docker镜像

js 复制代码
docker images | grep next

6. 删除镜像

1. 删除镜像

js 复制代码
docker rmi <image_name>

rmi:remove image的缩写

<image_name>:要删除的镜像名称或者镜像id

2. 删除所有没有标签的镜像

js 复制代码
docker image prune

3. 删除所有未被容器使用的镜像

js 复制代码
docker image prune -a

7. 推送镜像

1. 私有镜像库设置

docker默认只支持https协议,如果私有库是http协议或者ip地址,需设置insecure-registries

windows配置,docker desktop -> 设置 -> Docker Engine 添加配置

js 复制代码
//域名或ip地址,不用加协议
"insecure-registries": ["www.test.com","11.11.11.11"]

2. 阿里云镜像库

除了搭建私有镜像仓库,还可以使用阿里云镜像库

阿里云容器镜像服务:cr.console.aliyun.com/cn-hangzhou...

3. 登录镜像库

js 复制代码
docker login --username=caowj registry.cn-hangzhou.aliyuncs.com

--username:用户名

registry.cn-hangzhou.aliyuncs.com:指定镜像仓库地址,如果未指定,默认为官方仓库 Docker Hub

4. 镜像标签

给镜像打标签

js 复制代码
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

SOURCE_IMAGE[:TAG]:源镜像

TARGET_IMAGE[:TAG]:更改后的镜像名([]代表可选,不传为latest)

例如:

js 复制代码
docker tag next nodejs/next

5. 推送镜像

js 复制代码
docker push NAME[:TAG]

NAME:要推送的镜像名称

:TAG\]: 可选的镜像标签。如果不指定标签,默认使用 latest 标签 例如: ```js docker push nodejs/next ``` ## 6. 退出登录 ```js docker logout ``` # 8. 构建容器 **1. 拉取镜像** 容器都是基于镜像构建的,在服务器先拉取刚刚推送的镜像 ```js docker pull nodejs/next ``` **2. 构建容器** ```js docker run -di --name=next -p 3000:3000 -v /data:/app/.next/cache nodejs/next ``` -d:容器在后台运行 -i:允许你对容器内的 STDIN 进行交互 --name:启动的容器名 -p \[主机\]:\[容器\]:端口映射 -v /data:/app/.next/cache:将/app/.next/cache的文件与主机/data目录关联起来,实现docker数据持久化保存 nodejs/next:启动的镜像名 # 9. 查看容器 **1. 进入容器内部** ```js docker exec -it next /bin/sh ``` docker exec:进入容器内部 -it:以交互式模式进入容器 /bin/sh:进入容器后使用shell **2. 查看容器结构** ```js ls -a ``` ls:列出当前目录下的所有文件和目录 -a:显示包括隐藏文件(以 . 开头的文件)在内的所有内容 **3. 退出容器** ```js exit ``` # 10. 删除容器 **1. 查看容器** 查看运行中的容器 ```js docker ps ``` 查看所有容器 ```js docker ps -a ``` **2. 删除容器** 根据 id 删除容器 ```js docker rm -f e31f ``` rm:remove缩写 -f:强制删除,即使容器在运行 **3. 删除所有停止的容器** ```js docker container prune ``` # 结尾 本文只介绍了Next.js + Docker的基本使用,除此以外还有更多的用法,例如通过yml文件简化docker run命令等。后续有时间将会另起一篇进行介绍。也可自行去了解,Docker文档地址:[docs.docker.com/guides/get-...](https://link.juejin.cn?target=https%3A%2F%2Fdocs.docker.com%2Fguides%2Fget-started%2F "https://docs.docker.com/guides/get-started/") 对Next.js感兴趣的,可先关注我,后续将继续更新相关内容

相关推荐
满怀10159 分钟前
【HTML 全栈进阶】从语义化到现代 Web 开发实战
前端·html
繁依Fanyi17 分钟前
用 UniApp 构建习惯打卡 App —— HabitLoop 开发记
javascript·uni-app·codebuddy首席试玩官
东锋1.320 分钟前
前端动画库 Anime.js 的V4 版本,兼容 Vue、React
前端·javascript·vue.js
满怀101533 分钟前
【Flask全栈开发指南】从零构建企业级Web应用
前端·python·flask·后端开发·全栈开发
小杨升级打怪中1 小时前
前端面经-webpack篇--定义、配置、构建流程、 Loader、Tree Shaking、懒加载与预加载、代码分割、 Plugin 机制
前端·webpack·node.js
Yvonne爱编码1 小时前
CSS- 4.4 固定定位(fixed)& 咖啡售卖官网实例
前端·css·html·状态模式·hbuilder
SuperherRo2 小时前
Web开发-JavaEE应用&SpringBoot栈&SnakeYaml反序列化链&JAR&WAR&构建打包
前端·java-ee·jar·反序列化·war·snakeyaml
大帅不是我2 小时前
Python多进程编程执行任务
java·前端·python
前端怎么个事2 小时前
框架的源码理解——V3中的ref和reactive
前端·javascript·vue.js
Ciito2 小时前
将 Element UI 表格元素导出为 Excel 文件(处理了多级表头和固定列导出的问题)
前端·vue.js·elementui·excel