Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/myxiaoao/nextjs-docker
部署 NextJS 与 App Router:不再只是 Vercel 的专属
https://github.com/myxiaoao/nextjs-docker
docker docker-compose nextjs vercel
Last synced: 13 days ago
JSON representation
部署 NextJS 与 App Router:不再只是 Vercel 的专属
- Host: GitHub
- URL: https://github.com/myxiaoao/nextjs-docker
- Owner: myxiaoao
- License: mit
- Created: 2024-10-21T06:14:39.000Z (27 days ago)
- Default Branch: master
- Last Pushed: 2024-10-21T07:13:12.000Z (27 days ago)
- Last Synced: 2024-10-23T08:21:30.132Z (25 days ago)
- Topics: docker, docker-compose, nextjs, vercel
- Language: Dockerfile
- Homepage:
- Size: 5.86 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 部署 NextJS 与 App Router:不再只是 Vercel 的专属
存在一种误解,认为在 Vercel 基础设施之外部署使用新 App Router 的 NextJS 应用很困难。
事实并非如此。
本文将解释如何使用 Docker 和 Docker Compose 部署 NextJS 应用,其中 Nginx 负责提供静态资源并充当反向代理。
## 构建基石:涉及到的技术栈
该部署过程中使用的工具是:
1. NextJS:具有 App Router 的 React 框架。
2. Docker:容器化平台。
3. Docker Compose:管理多容器设置的工具。
4. Nginx:处理静态资源和反向代理请求的 Web 服务器。### 第一步:准备您的 Next.js 应用
第一步是为 NextJS 应用准备部署。关键是在 `next.config.mjs` 文件中使用 `standalone` 输出选项。这会创建一个包含所有必要依赖项的独立构建。
以下是 `next.config.mjs` 的大致样子:
```react
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
};export default nextConfig;
```> 此配置更改告知 NextJS 将应用程序运行所需的所有内容打包在一起。
### 第二步:编写 Dockerfile
下一步是创建 Dockerfile。使用多阶段构建过程以保持最终镜像高效。
```dockerfile
# Stage 1: Dependencies
FROM node:22.6.0-alpine3.20 AS deps
WORKDIR /appCOPY package.json package-lock.json ./
RUN npm ci --only=production --no-audit --prefer-offline --silent# Stage 2: Builder
FROM node:22.6.0-alpine3.20 AS builder
WORKDIR /appENV NEXT_TELEMETRY_DISABLED 1
COPY --from=deps /app/node_modules ./node_modules
COPY . .RUN npm run build
# Stage 3: Runner (Node.js app)
FROM node:22.6.0-alpine3.20 AS runner
WORKDIR /appENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/.next/standalone ./EXPOSE 3000
CMD ["node", "server.js"]
# Stage 4: Nginx
FROM nginx:1.27.0-alpine3.19 AS nginx# Copy the built Next.js static files
COPY --from=builder /app/public /usr/share/nginx/html
COPY --from=builder /app/.next/static /usr/share/nginx/html/_next/staticCOPY --from=builder /app/app/favicon.ico /usr/share/nginx/html/favicon.ico
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
该多阶段构建包含:
1. 依赖阶段:安装生产依赖项。
2. 构建阶段:构建 NextJS 应用,创建独立构建。
3. 运行阶段:设置运行 NextJS 应用的环境。
4. Nginx 阶段:准备 Nginx 服务器静态文件并提供反向代理功能。### 第三步:配置 Nginx
Nginx 已配置为适配当前应用的内容。以下是 `nginx.conf` 文件内容:
```nginx
user nginx;
worker_processes auto;error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;events {
worker_connections 1024;
multi_accept on;
use epoll;
}http {
include /etc/nginx/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"';access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;upstream nextjs_upstream {
server nextjs:3000;
keepalive 64;
}server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;location / {
proxy_pass http://nextjs_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}location /_next/static {
alias /usr/share/nginx/html/_next/static;
expires 365d;
access_log off;
add_header Cache-Control "public, max-age=31536000, immutable";
}location /static {
expires 365d;
access_log off;
add_header Cache-Control "public, max-age=31536000, immutable";
}location = /favicon.ico {
log_not_found off;
access_log off;
expires 365d;
add_header Cache-Control "public, max-age=31536000, immutable";
}location = /robots.txt {
log_not_found off;
access_log off;
}gzip_static on;
}
}
```此配置主要涉及以下内容:
1. 为 NextJS 应用设置上游服务器。
2. 配置处理不同类型请求的处理方式。
3. 设置缓存和性能优化。### 第四步:用 Docker Compose 编排
Docker Compose 用于协调 NextJS 应用程序和 Nginx 镜像。以下是 `docker-compose.yml` 文件内容:
```docker-compose
services:
nextjs:
build:
context: .
target: runner
container_name: nextjs-app
restart: alwaysnginx:
build:
context: .
target: nginx
container_name: nextjs-nginx
restart: always
ports:
- "80:80"
depends_on:
- nextjsnetworks:
default:
name: nextjs-network
```此配置主要涉及以下内容:
1. 定义了两个服务:NextJS 应用和 Nginx。
2. 为它们建立一个通信网络。
3. 暴露端口 80 以供传入的 Web 流量使用。## 部署流程
准备要部署应用程序:
1. 确保服务器上已安装 Docker 和 Docker Compose。
2. 上传 NextJS 项目文件、`Dockerfile`、`nginx.conf`和`docker-compose.yml`到服务器。
3. 切换到终端中的项目目录。
4. 运行命令:`docker-compose up -d --build` 。此命令构建 Docker 镜像并以分离模式启动容器。
## 结论
使用 Docker 和 Nginx,在 Vercel 之外部署 NextJS 应用并使用 App Router 是可行的。这种设置创建了一个可以控制基础设施的部署环境。