MemoBox 部署方案与实践
MemoBox 是一个兼容 memos 数据格式的个人私人朋友圈项目,采用 Next.js + Docker + Nginx 架构部署。本文档详细记录项目的部署方案、架构设计和最佳实践。
技术栈:Next.js 16、React 19、TypeScript、SQLite (better-sqlite3)、Docker、Nginx
部署环境:腾讯云 Ubuntu 服务器
📚 目录
1. 项目概述
1.1 项目特点
- 全栈应用:Next.js App Router,前后端一体化
- 数据存储:SQLite 数据库(better-sqlite3)
- 文件存储:本地文件系统存储资源文件
- 容器化部署:Docker + Docker Compose
- 反向代理:双层 Nginx 架构
1.2 技术选型理由
| 技术 | 选型理由 |
|---|---|
| Next.js 16 | App Router、Server Components、API Routes 一体化 |
| SQLite | 轻量级、无需独立数据库服务、适合个人项目 |
| Docker | 环境一致性、易于部署和维护 |
| Nginx | 高性能反向代理、静态资源缓存 |
2. 部署架构设计
2.1 整体架构图
用户访问 memo.muliminty.online
↓
宿主机主 Nginx (80/443) ← 对外暴露,处理 HTTPS
↓ 反向代理到 localhost:3001
Docker Nginx 容器 (3001:80) ← 宿主机端口 3001
↓ 通过 Docker 网络 memobox-network
Next.js 应用容器 (3000) ← 仅容器内,不对外暴露
↓
SQLite 数据库 + 资源文件 (Docker Volume)
2.2 端口规划
| 端口 | 服务 | 说明 | 访问方式 |
|---|---|---|---|
| 80 | 宿主机主 Nginx | HTTP 入口(生产环境) | http://memo.muliminty.online |
| 443 | 宿主机主 Nginx | HTTPS 入口(生产环境) | https://memo.muliminty.online |
| 3001 | Docker Nginx 容器 | 容器端口映射 | http://localhost:3001 |
| 3000 | Next.js 应用容器 | 容器内端口,不对外暴露 | 仅通过 Docker 网络访问 |
2.3 架构设计要点
-
双层 Nginx 架构
- 宿主机 Nginx:处理 HTTPS、SSL 证书、域名路由
- Docker Nginx:应用层反向代理、静态资源缓存
-
容器网络隔离
- 使用 Docker 自定义网络
memobox-network - Next.js 应用不直接暴露端口,通过 Nginx 访问
- 使用 Docker 自定义网络
-
数据持久化
- 使用 Docker Volumes 挂载数据目录
- 支持本地开发和生产环境不同路径配置
3. Docker 配置详解
3.1 Dockerfile 多阶段构建
# 使用 Node.js 官方镜像
FROM node:20-alpine AS base
# 安装系统依赖(better-sqlite3 需要)
RUN apk add --no-cache python3 make g++
# 安装依赖阶段
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
# 构建阶段
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# 生产阶段
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# 创建非 root 用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# 复制必要文件
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/lib ./lib
# 创建数据目录
RUN mkdir -p /app/data /app/backups
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]关键点:
- 多阶段构建:减少最终镜像体积
- 非 root 用户:提高安全性
- standalone 模式:Next.js 独立部署,只包含必要文件
3.2 Next.js Standalone 配置
// next.config.js
const nextConfig = {
output: 'standalone', // 启用独立部署模式
serverExternalPackages: ['better-sqlite3'], // 外部包不打包
experimental: {
serverActions: {
bodySizeLimit: '50mb', // 文件上传大小限制
},
},
}standalone 模式优势:
- 只包含运行时的必要文件
- 减少镜像体积
- 提高启动速度
3.3 Docker Compose 配置
version: '3.8'
services:
memobox:
build:
context: .
dockerfile: Dockerfile
platform: linux/amd64 # 指定平台,避免架构问题
container_name: memobox
restart: unless-stopped # 自动重启策略
# 不直接暴露端口,只通过 Nginx 访问
# ports: # 注释掉,不暴露端口
environment:
- NODE_ENV=${NODE_ENV:-production}
- DATABASE_PATH=/app/data/memos_prod.db
- STORAGE_PATH=/app/data/resources
- THUMBNAIL_CACHE_PATH=/app/data/.thumbnail_cache
- COOKIE_SECURE=${COOKIE_SECURE:-false}
volumes:
- ${DATA_PATH:-./data}:/app/data
- ${BACKUPS_PATH:-./backups}:/app/backups
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- memobox-network
nginx:
image: nginx:alpine
container_name: memobox-nginx
ports:
- "3001:80" # 宿主机 3001 映射到容器内 80
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/app.conf
- ./nginx/logs:/var/log/nginx
restart: unless-stopped
depends_on:
- memobox
networks:
- memobox-network
networks:
memobox-network:
driver: bridge配置要点:
- 平台指定:
platform: linux/amd64避免 ARM 架构问题 - 健康检查:自动检测容器健康状态
- 网络隔离:使用自定义网络,容器间通信
- 数据持久化:通过 volumes 挂载数据目录
4. Nginx 配置详解
4.1 Docker 内 Nginx 配置
# nginx/nginx.conf
server {
listen 80;
listen [::]:80;
server_name memo.muliminty.online www.memo.muliminty.online;
charset utf-8;
client_max_body_size 50M; # 允许上传大文件
access_log /var/log/nginx/app_access.log;
error_log /var/log/nginx/app_error.log;
# 反向代理到 Next.js 应用
location / {
proxy_pass http://memobox:3000; # 通过 Docker 网络访问
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
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;
proxy_cache_bypass $http_upgrade;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置(提高性能)
proxy_buffering off;
}
# 健康检查端点
location /api/health {
proxy_pass http://memobox:3000/api/health;
access_log off;
}
# 静态资源缓存
location /_next/static {
proxy_pass http://memobox:3000;
proxy_cache_valid 200 60m;
add_header Cache-Control "public, immutable";
}
# 其他静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://memobox:3000;
proxy_cache_valid 200 1d;
expires 1d;
add_header Cache-Control "public, immutable";
}
}配置要点:
- WebSocket 支持:
Upgrade和Connection头支持 WebSocket - 静态资源缓存:Next.js 静态资源和图片缓存优化
- 大文件上传:
client_max_body_size 50M
4.2 宿主机主 Nginx 配置
# /etc/nginx/sites-available/memo.muliminty.online
server {
listen 80;
listen [::]:80;
server_name memo.muliminty.online www.memo.muliminty.online;
# 反向代理到 Docker Nginx 容器
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
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;
proxy_cache_bypass $http_upgrade;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}HTTPS 配置(使用 Let’s Encrypt):
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx -y
# 获取证书(会自动配置 Nginx)
sudo certbot --nginx -d memo.muliminty.online -d www.memo.muliminty.online5. 环境变量管理
5.1 环境变量分类
Docker Compose 配置变量(用于 volumes 挂载):
DATA_PATH=/opt/memobox/data
BACKUPS_PATH=/opt/memobox/backups
NODE_ENV=production
COOKIE_SECURE=true应用运行时变量(容器内路径):
DATABASE_PATH=/app/data/memos_prod.db
STORAGE_PATH=/app/data/resources
THUMBNAIL_CACHE_PATH=/app/data/.thumbnail_cache5.2 不同环境配置
本地开发(Mac):
# .env.local
DATA_PATH=./data
BACKUPS_PATH=./backups
NODE_ENV=development
COOKIE_SECURE=false生产环境(Ubuntu 服务器):
# .env
DATA_PATH=/opt/memobox/data
BACKUPS_PATH=/opt/memobox/backups
NODE_ENV=production
COOKIE_SECURE=true5.3 环境变量使用原则
-
路径配置:
- 本地开发:使用相对路径
./data - 生产环境:使用绝对路径
/opt/memobox/data
- 本地开发:使用相对路径
-
安全配置:
- HTTP 环境:
COOKIE_SECURE=false - HTTPS 环境:
COOKIE_SECURE=true(必须)
- HTTP 环境:
-
数据隔离:
- 不同环境使用不同的数据目录
- 避免数据污染
6. 数据持久化方案
6.1 数据目录结构
/opt/memobox/
├── data/ # 数据目录
│ ├── memos_prod.db # SQLite 数据库
│ ├── resources/ # 资源文件(图片、文档等)
│ │ ├── 2024/
│ │ │ ├── 01/
│ │ │ │ └── xxx.jpg
│ │ └── ...
│ └── .thumbnail_cache/ # 缩略图缓存
└── backups/ # 备份目录
└── memobox-backup-*.tar.gz
6.2 Docker Volume 挂载
volumes:
- ${DATA_PATH:-./data}:/app/data
- ${BACKUPS_PATH:-./backups}:/app/backups挂载说明:
- 宿主机路径:
/opt/memobox/data(生产环境) - 容器内路径:
/app/data - 数据持久化:容器删除后数据不丢失
6.3 数据备份方案
自动备份脚本:
#!/bin/bash
# scripts/backup.sh
BACKUP_DIR="./backups"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="memobox-backup-${TIMESTAMP}.tar.gz"
# 创建备份
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" \
--exclude='.thumbnail_cache' \
./data/memos_prod.db \
./data/resources
echo "备份完成: ${BACKUP_FILE}"定时备份(Crontab):
# 每天凌晨 2 点自动备份
0 2 * * * /path/to/MemoBox/scripts/backup.sh7. 完整部署流程
7.1 首次部署步骤
# 1. 克隆项目
git clone git@github.com:Muliminty/MemoBox.git
cd MemoBox
# 2. 配置环境变量
cp .env.production.example .env
nano .env # 修改 DATA_PATH 和 BACKUPS_PATH
# 3. 创建数据目录
sudo mkdir -p /opt/memobox/data /opt/memobox/backups
sudo chown -R $USER:$USER /opt/memobox/data /opt/memobox/backups
# 4. 导入数据(如果有备份)
./scripts/import.sh /path/to/backup.tar.gz
# 5. 构建并启动
docker-compose up -d --build
# 6. 配置宿主机 Nginx
sudo nano /etc/nginx/sites-available/memo.muliminty.online
# 添加配置(见 4.2 节)
# 7. 启用配置
sudo ln -s /etc/nginx/sites-available/memo.muliminty.online /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# 8. 配置 HTTPS(可选)
sudo certbot --nginx -d memo.muliminty.online7.2 更新部署流程
# 1. 拉取最新代码
git pull
# 2. 备份数据(重要!)
./scripts/export.sh
# 3. 重新构建镜像
docker-compose build
# 4. 停止旧容器
docker-compose down
# 5. 启动新容器
docker-compose up -d
# 6. 查看日志确认
docker-compose logs -f7.3 一键部署脚本
项目提供了自动化部署脚本 scripts/deploy.sh:
#!/bin/bash
# 功能:
# 1. 检查 Docker 环境
# 2. 检查 .env 文件
# 3. 创建数据目录
# 4. 构建并启动服务
# 5. 验证服务状态
./scripts/deploy.sh8. 最佳实践与注意事项
8.1 安全建议
-
使用 HTTPS:
- 生产环境必须使用 HTTPS
- 设置
COOKIE_SECURE=true - 使用 Let’s Encrypt 免费证书
-
容器安全:
- 使用非 root 用户运行(已配置)
- 定期更新基础镜像
- 限制容器资源使用
-
数据安全:
- 定期备份数据
- 备份文件加密存储
- 限制数据目录访问权限
8.2 性能优化
-
Nginx 缓存:
- 静态资源缓存(已配置)
- Next.js 构建产物缓存
-
数据库优化:
- SQLite 适合小到中型应用
- 定期执行
VACUUM优化数据库
-
资源文件优化:
- 图片自动生成缩略图
- 使用 WebP 格式(可选)
8.3 监控与维护
查看容器状态:
docker-compose ps
docker-compose logs -f memobox
docker-compose logs -f nginx健康检查:
# 检查应用健康状态
curl http://localhost:3001/api/health
# 检查容器健康状态
docker inspect memobox | grep Health -A 10资源监控:
# 查看容器资源使用
docker stats
# 查看磁盘使用
df -h
du -sh /opt/memobox/data8.4 常见问题排查
问题 1:502 Bad Gateway
原因:Next.js 应用未启动或端口不对
解决:
# 检查容器状态
docker-compose ps
# 查看应用日志
docker-compose logs memobox
# 检查端口映射
docker port memobox-nginx问题 2:数据库文件权限错误
原因:数据目录权限不正确
解决:
# 检查权限
ls -la /opt/memobox/data
# 修改权限
sudo chown -R 1001:1001 /opt/memobox/data问题 3:静态资源 404
原因:Next.js standalone 模式文件缺失
解决:
# 检查构建产物
docker-compose exec memobox ls -la /app/.next/static
# 重新构建
docker-compose build --no-cache
docker-compose up -d8.5 数据迁移
导出数据:
./scripts/export.sh
# 生成: backups/memobox-backup-YYYYMMDD-HHMMSS.tar.gz导入数据:
# 在新服务器上
./scripts/import.sh backups/memobox-backup-*.tar.gz迁移步骤:
- 在旧服务器导出数据
- 将备份文件传输到新服务器
- 在新服务器部署应用
- 导入备份数据
- 启动服务
📋 部署检查清单
部署前检查
- Docker 和 Docker Compose 已安装
- 环境变量文件
.env已配置 - 数据目录已创建并设置权限
- 端口 3001 未被占用
- 防火墙规则已配置(80/443)
部署后验证
- 容器正常运行:
docker-compose ps - 应用健康检查通过:
curl http://localhost:3001/api/health - 宿主机 Nginx 配置正确
- 域名解析正确
- HTTPS 证书配置(如使用)
- 数据目录挂载正确
生产环境检查
-
COOKIE_SECURE=true已设置 -
NODE_ENV=production已设置 - 数据备份脚本已配置
- 定时备份已设置(Crontab)
- 日志目录已配置
- 监控告警已配置(可选)
🔗 相关链接
项目文档
- MemoBox README — 项目说明
- 部署备忘 — 快速部署指南
- 环境变量配置 — 环境变量说明
技术文档
- 服务器多项目部署规范 — 多项目部署规范
- Docker 核心概念 — Docker 基础
- Nginx 多项目配置 — Nginx 配置
最后更新:2026-01-28
项目地址:https://github.com/Muliminty/MemoBox