feat(deploy): 个人 NAS 单机 Docker 部署方案

适用:内网 / 家庭 / 小团队(≤50 并发),无 K8s 需求。
特性:单容器 + SQLite + 端口暴露,最小维护成本。

新增:
- deploy/nas/Dockerfile: python:3.11-slim 基础镜像 + 非 root + HEALTHCHECK
- deploy/nas/start.sh: flask db upgrade 幂等迁移 + gunicorn (2 workers × 4 threads)
- deploy/nas/docker-compose.yaml: 单服务 + 4 个命名卷 (db/logs/session/upload) + 资源限制
- docs/deployment-nas.md: 完整部署/备份/升级/排障指南

完善:
- .env.example: 改为生产环境导向 (PEAR_ENV=pro,SECRET_KEY 必填)
- .dockerignore: 排除 deploy/dev (开发用容器配置)、tests/截图、一次性脚本
- applications/view/public/__init__.py: 注释说明 /healthz 已在 applications/view/health.py 注册

复用现有:
- /healthz 接口 (applications/view/health.py) 含 DB 探活,DB 不可达返回 503
  → 容器 HEALTHCHECK 直接用 /healthz 即可

⚠️ 本机无 docker,未执行 docker build 验证;已静态校验 YAML/bash 语法、
   文件路径、.env 字段消费、ProConfig 严格性、/healthz 端点可用性。
   首次 NAS 上部署时跑一遍文档步骤即可。
This commit is contained in:
bwstudio
2026-09-06 18:35:31 +08:00
parent 0ffc103e46
commit 98edfdaf2d
7 changed files with 498 additions and 41 deletions
+81
View File
@@ -0,0 +1,81 @@
# =====================================================
# Pear Admin Flask - 个人 NAS 单机部署
# =====================================================
# 使用:
# 1) cp .env.example .env 并修改 SECRET_KEY
# 2) docker compose -f deploy/nas/docker-compose.yaml up -d
# 3) 访问 http://NAS_IP:5000
#
# 数据持久化:
# - pear_dbSQLite 数据库文件
# - flask_logs:容器内 /app/logsgunicorn + Flask 日志)
# - flask_sessionFlask-Session 文件会话
# - flask_upload:上传的图片/文件
# =====================================================
services:
flask:
build:
context: ../.. # 项目根目录(含 requirements.txt
dockerfile: deploy/nas/Dockerfile
image: pear-admin-nas:latest
container_name: pear-admin-nas
restart: unless-stopped
ports:
- "5000:5000" # 容器 5000 → NAS 5000;可改为 127.0.0.1:5000:5000 仅本地访问
# 环境变量注入(生产环境用 .env 自动读取)
env_file:
- ../../.env
# 数据持久化卷(NAS 上是命名卷;如想直挂目录,把左边改为宿主路径)
volumes:
- pear_db:/app/pear.db # SQLite 数据库
- flask_logs:/app/logs # gunicorn / Flask 日志
- flask_session:/app/flask_session # Flask-Session 文件会话
- flask_upload:/app/static/upload # 上传的图片
# 资源限制(NAS 推荐;按需调整)
deploy:
resources:
limits:
cpus: '2.0' # 单容器最多用 2 核
memory: 1024M # 1 GB 上限
reservations:
cpus: '0.5'
memory: 256M
# 健康检查:applications/view/health.py 提供 /healthz
# - 200DB OK
# - 503DB 不可达(让容器被标 unhealthy)
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:5000/healthz"]
interval: 30s
timeout: 10s
start_period: 40s
retries: 3
# 网络模式默认 bridge;如 NAS 上启用了 host 网络可获得更好的局域网性能:
# network_mode: host
networks:
- pear_net
# =====================================================
# 命名卷:首次 `docker compose up` 自动创建
# 查看: docker volume ls | grep pear
# 备份: docker run --rm -v pear-admin-nas_pear_db:/data -v $(pwd)/bak:/backup \
# alpine cp /data/pear.db /backup/pear-$(date +%F).db
# =====================================================
volumes:
pear_db:
name: pear-admin-nas_pear_db
flask_logs:
name: pear-admin-nas_logs
flask_session:
name: pear-admin-nas_session
flask_upload:
name: pear-admin-nas_upload
networks:
pear_net:
driver: bridge