# ===================================================== # Pear Admin Flask - 个人 NAS / 单机部署 Dockerfile # ===================================================== # 适用场景:内网访问 / 少量并发 / 数据量小 # 基础:python:3.11-slim(~150 MB),无 MySQL,纯 SQLite # # 构建: docker build -f deploy/nas/Dockerfile -t pear-admin-nas . # 运行: docker compose -f deploy/nas/docker-compose.yaml up -d # ===================================================== FROM python:3.11-slim # 容器内时区与 Python 输出 ENV TZ=Asia/Shanghai \ PYTHONUNBUFFERED=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_NO_CACHE_DIR=1 \ PEAR_ENV=pro \ PEAR_DATA_DIR=/app/data \ FLASK_APP=app.py # 安装时区数据 + 健康检查用的 curl # (curl 在 slim 里已有,但保持显式声明便于以后切到 alpine) RUN apt-get update \ && apt-get install -y --no-install-recommends curl tzdata sqlite3 \ && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo $TZ > /etc/timezone \ && rm -rf /var/lib/apt/lists/* # 非 root 运行(生产最佳实践) RUN useradd -m -u 1001 appuser WORKDIR /app # 先只 copy 依赖文件 → 利用 Docker 缓存;requirements 不变则跳过 pip install COPY requirements.txt ./ RUN pip install -r requirements.txt \ && pip install gunicorn==21.2.0 # 再 copy 全部源码 COPY --chown=appuser:appuser . . # 数据目录单独建好并 chown 给 appuser(uid 1001)。 # /app/data 由卷挂载覆盖,但容器刚启动时如果宿主目录是空的, # 子目录(backup/ flask_session/ 等)需要 appuser 自己能写。 RUN mkdir -p /app/data/backup /app/data/flask_session /app/data/logs /app/data/upload \ && chown -R appuser:appuser /app/data # 启动脚本加执行权限 RUN chmod +x /app/deploy/nas/start.sh /app/deploy/nas/backup.sh # 切换到非 root USER appuser EXPOSE 5000 # 容器健康检查:访问 /healthz 接口(applications/view/health.py 提供,DB 不可达返回 503) HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -fsS http://localhost:5000/healthz || exit 1 CMD ["/app/deploy/nas/start.sh"]