56 lines
2.8 KiB
Docker
56 lines
2.8 KiB
Docker
# 部门关键任务追踪看板 · 运行镜像
|
||
#
|
||
# 构建:docker build -t unis-board . (日常部署建议用 ./deploy.sh up)
|
||
# 跑: docker run -d -p 8770:8770 -v $PWD/data:/app/data unis-board
|
||
#
|
||
# 镜像里只有依赖和代码,数据库/附件都在 data/,靠 bind mount 挂进来。
|
||
# data/ 已被 .dockerignore 排除,不会把本机 board.db 打进镜像。
|
||
#
|
||
# 基础镜像。国内直连 docker.io 会在 load metadata 阶段 TLS 超时,所以支持指成本地已有的镜像:
|
||
# docker pull python:3.12-slim && docker build --build-arg BASE_IMAGE=python:3.12-slim .
|
||
# ./deploy.sh 会优先用本地已有的同名镜像,不会去联网试各种加速站。
|
||
ARG BASE_IMAGE=python:3.12-slim
|
||
FROM ${BASE_IMAGE}
|
||
|
||
ENV PYTHONUNBUFFERED=1 \
|
||
PYTHONDONTWRITEBYTECODE=1 \
|
||
PIP_NO_CACHE_DIR=1 \
|
||
PIP_DISABLE_PIP_VERSION_CHECK=1
|
||
|
||
# 业务代码用 datetime.now() 取本地时间(周期/周次/入库时间/更新时间),
|
||
# 容器默认 UTC 会让这些日期整体差 8 小时,所以必须显式设时区(compose 里的 TZ 会覆盖这里)。
|
||
ENV TZ=Asia/Shanghai
|
||
|
||
WORKDIR /app
|
||
|
||
# 依赖单独一层:改业务代码不触发重装依赖
|
||
COPY requirements.txt ./
|
||
# pip 源:默认清华源(国内直连 pypi.org 基本超时,而且换基础镜像/代理都救不了它,
|
||
# 构建容器里的请求只能靠这里换源)。境外机器或内网自建源就覆盖:
|
||
# docker build --build-arg PIP_INDEX_URL=https://pypi.org/simple .
|
||
# ./deploy.sh up 会自动探测可用源并写进 .env,正常不用手工传。
|
||
ARG PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
||
RUN pip install --retries 5 --timeout 60 -i "$PIP_INDEX_URL" -r requirements.txt
|
||
# 用 MySQL 部署时放开下面这行(与 requirements.txt 的注释一致)
|
||
# RUN pip install "pymysql>=1.1" "cryptography>=42.0"
|
||
|
||
COPY app ./app
|
||
COPY web ./web
|
||
COPY scripts ./scripts
|
||
|
||
# 上传件 / 导出件目录;SQLite 库同样落在这里,实际内容由 volume 提供
|
||
RUN mkdir -p data/uploads data/exports
|
||
|
||
# 容器内固定监听 8770,对外端口由 compose 的 HOST_PORT 控制。
|
||
# 镜像默认以 root 运行:macOS 上 bind mount 只有 root 写 data/ 最省心。
|
||
# Linux 上想换成非特权账号,在 compose 里加 user: "1000:1000"
|
||
#(前提是 ./data 的属主也是这个 uid,否则 SQLite 写不进去)。
|
||
ENV PORT=8770
|
||
EXPOSE 8770
|
||
|
||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||
CMD python -c "import os,urllib.request;urllib.request.urlopen('http://127.0.0.1:%s/health' % os.environ.get('PORT','8770'),timeout=3).read()"
|
||
|
||
# 首次启动建表 + 预置分类(幂等,不覆盖已有数据);内置角色与管理员账号由 app/main.py 启动时补齐
|
||
CMD ["sh", "-c", "python scripts/init_db.py && exec python -m uvicorn app.main:app --host 0.0.0.0 --port \"${PORT:-8770}\""]
|