# 部门关键任务追踪看板 · 运行镜像 # # 构建: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}\""]