-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathDockerfile
More file actions
111 lines (89 loc) · 4.33 KB
/
Copy pathDockerfile
File metadata and controls
111 lines (89 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# BeeCount-Cloud Dockerfile
# 多阶段构建:frontend (pnpm + Vite) + Python (FastAPI + Alembic)
# ===== Stage 1: frontend 构建 =====
FROM node:20-alpine AS frontend-builder
WORKDIR /workspace/frontend
RUN corepack enable
# 先只拷 lock / workspace / 各 package.json,让依赖层可以被 cache 住。
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml /workspace/frontend/
COPY frontend/apps/web/package.json /workspace/frontend/apps/web/package.json
COPY frontend/packages/api-client/package.json /workspace/frontend/packages/api-client/package.json
COPY frontend/packages/ui/package.json /workspace/frontend/packages/ui/package.json
COPY frontend/packages/web-features/package.json /workspace/frontend/packages/web-features/package.json
RUN pnpm install --frozen-lockfile || pnpm install --no-frozen-lockfile
COPY frontend /workspace/frontend
ARG VITE_API_BASE_URL=/api/v1
ARG VERSION=dev
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
ENV VITE_APP_VERSION=$VERSION
RUN pnpm -C apps/web build
# ===== Stage 1.5: docs index 拉取 =====
# 从 BeeCount-Website 拉构建好的 RAG 索引(由 Website CI 维护)。
# Website 在 docs 改动时已经 build 好 sqlite 提交回 main,Cloud 这边只 cp。
# 详见 .docs/web-cmdk-ai-doc-search.md。
FROM alpine/git:latest AS docs-index-fetcher
ARG DOCS_INDEX_REPO=https://github.com/TNT-Likely/BeeCount-Website.git
ARG DOCS_INDEX_BRANCH=main
RUN git clone --depth 1 --branch ${DOCS_INDEX_BRANCH} ${DOCS_INDEX_REPO} /website || \
mkdir -p /website/data
RUN ls /website/data 2>/dev/null || echo 'no docs index found (Website CI 未跑或 repo private,A1 文档 Q&A 将降级)'
# ===== Stage 2: Python 运行环境 =====
FROM python:3.12-slim
ARG VERSION=dev
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
# 系统依赖:
# - tzdata: 时区数据
# - curl: HEALTHCHECK 用(比 Python urllib 省事)
# - rclone: 备份模块用,subprocess 调用推数据到对象存储。
# Debian 12 仓库版本 1.60.x,S3/R2/WebDAV/B2/GDrive/OneDrive 全支持。
# 注:age 加密走 pyrage Python binding(见 requirements.txt),不需要装
# age CLI。用户灾难恢复在自己机器装 age 即可。
RUN apt-get update && apt-get install -y --no-install-recommends \
tzdata \
curl \
rclone \
&& rm -rf /var/lib/apt/lists/*
# 先装 Python 依赖(单独一层,改业务代码时不用重装)
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# 后端代码
COPY alembic.ini /app/alembic.ini
COPY alembic /app/alembic
COPY src /app/src
COPY server.py /app/server.py
COPY scripts /app/scripts
# 静态资源(前端构建产物)
COPY --from=frontend-builder /workspace/frontend/apps/web/dist /app/static
# RAG docs 索引(没拉到时是空目录,server 会优雅降级到 fallback 提示)
COPY --from=docs-index-fetcher /website/data /app/data
# 数据目录:所有持久化数据(DB / 附件 / 备份 / 头像)统一放 /data,
# 容器部署直接挂一个 volume 到 /data 就能全量备份。本地开发走 config.py
# 的相对路径默认值(./data/*),两种场景互不干扰。
RUN mkdir -p /data /app/logs
ENV APP_ENV=production \
DATA_DIR=/data \
DATABASE_URL=sqlite:////data/beecount.db \
BACKUP_STORAGE_DIR=/data/backups \
ATTACHMENT_STORAGE_DIR=/data/attachments \
RCLONE_CONFIG_PATH=/data/rclone.conf \
WEB_STATIC_DIR=/app/static \
ALLOW_APP_RW_SCOPES=true \
APP_VERSION=${VERSION}
# 记下版本号便于排查
RUN echo "${VERSION}" > /app/VERSION
# 默认时区(docker run 可通过 -e TZ=... 覆盖)。
# APScheduler 通过 tzlocal 自动从 TZ env 读取,镜像里 tzdata 已装,
# "0 4 * * *" 在容器本地 4 点触发。如 tzlocal 极少数情况失效(自定义
# minimal base),可显式设置 SCHEDULER_TIMEZONE=<IANA TZ> 兜底。
ENV TZ=Asia/Shanghai
EXPOSE 8080
# 健康检查:打根路径的 /healthz(app.get('/healthz') 直接挂在根,不在
# /api/v1/ 前缀下)。以前写成 /api/v1/healthz + fallback 到 /,每 30s 日志
# 里都多一条 404 噪声;这里直接打对的路径,/ 作二次兜底。
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD curl -fsSL http://localhost:8080/healthz \
|| curl -fsSL http://localhost:8080/ \
|| exit 1
CMD ["sh", "-c", "alembic upgrade head && uvicorn server:app --host 0.0.0.0 --port 8080"]