unis_manager/Dockerfile

56 lines
2.8 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 部门关键任务追踪看板 · 运行镜像
#
# 构建: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 build --build-arg BASE_IMAGE=docker.1ms.run/library/python:3.12-slim .
# ./deploy.sh up 会自动探测可用加速站并把结果写进 .env,正常情况下不用手工传。
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}\""]