- main.ts: `--role fsworker` dispatched before the rest of the module graph is loaded (other imports became dynamic); runs fsWorkerMain from the new `@umt/adapters/fsworker` export (~150 ms startup in the compiled binary) - fsproxy: default worker command picked per runtime (deno CLI -> `deno run fsworker.ts`, compiled binary -> `<execPath> --role fsworker`); stats expose workerKind; UMT_FS_TEST_HANG_AFTER_BYTES acceptance switch for containers - compile: --allow-run adds /app/umt-server (spawn self); start task allows deno - organize: replaced old file moved into the file-manager trash layout (<root>/.umt-trash/<day>/<uuid>/<rel>) and registered in trash_item, ledger result follows; organize.transfer log carries fsproxy stats - settings: autoInvestigateMode (investigate/recover) + max recover attempts - deploy.md: container verification (subprocess self, TIMEOUT -> SIGKILL x3) Co-Authored-By: Claude Opus 5.5 <[email protected]>
55 lines
3.1 KiB
Docker
55 lines
3.1 KiB
Docker
# 单容器镜像:一个 deno compile 出的 umt-server 二进制,同时承担 API(含 web 静态 SPA)与 worker。
|
|
# PostgreSQL 不在本镜像内,见 docker-compose.yml。
|
|
# 构建:docker build -t uhd-media-tool . 运行时版本锁定 Deno 2.9.7(ADR-004)
|
|
# ffprobe 取自静态构建镜像(单个 static-pie 二进制,约 135 MB;Debian 的 ffmpeg 包要拉 200+ 个依赖、约 450 MB)
|
|
ARG FFPROBE_IMAGE=mwader/static-ffmpeg:7.1.1
|
|
FROM ${FFPROBE_IMAGE} AS ffprobe
|
|
|
|
FROM denoland/deno:2.9.7 AS build
|
|
WORKDIR /src
|
|
COPY . .
|
|
RUN deno install --frozen
|
|
ARG APP_VERSION=""
|
|
ENV APP_VERSION=${APP_VERSION}
|
|
RUN deno task check:tokens && cd apps/web && deno task build
|
|
# --node-modules-dir=none + --exclude-unused-npm:只嵌入 server 依赖图可达的 npm 包(约 110 MB,而不是整个 node_modules)
|
|
# 权限在编译时固定:读写不限路径(库根/下载目录由用户挂载,位置不固定;写保护靠 /app root 只读 + 非 root 运行);
|
|
# --allow-run 只放 ffprobe(入库探测)、sha256sum(强制全量哈希走子进程,coreutils 自带)与 /app/umt-server 自身
|
|
# (fsproxy 把单个文件操作放进 `umt-server --role fsworker` 一次性子进程,挂死可 SIGKILL 回收;二进制必须装在 /app/umt-server)
|
|
RUN cd apps/server && deno task compile
|
|
|
|
FROM debian:trixie-slim
|
|
# gosu:root 修完 DATA_DIR 属主后降权;postgresql-client:备份/恢复脚本用 pg_dump/pg_restore/psql
|
|
# (trixie 自带 17 版客户端,可备份/恢复 16 版服务端)。Deno 自带根证书,不装 ca-certificates;健康探测用二进制自身的 fetch
|
|
# 国内网络可 --build-arg APT_MIRROR=mirrors.ustc.edu.cn 换源
|
|
ARG APT_MIRROR=""
|
|
RUN if [ -n "$APT_MIRROR" ]; then sed -i "s|deb.debian.org|$APT_MIRROR|g" /etc/apt/sources.list.d/debian.sources; fi \
|
|
&& apt-get update \
|
|
&& apt-get install -y --no-install-recommends gosu postgresql-client \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& groupadd --system --gid 10001 umt \
|
|
&& useradd --system --uid 10001 --gid 10001 --home-dir /data --no-create-home --shell /usr/sbin/nologin umt \
|
|
&& mkdir -p /data && chown 10001:10001 /data
|
|
WORKDIR /app
|
|
# /app 全部 root 属主、只读:运行用户(缺省 10001,可用 PUID/PGID 覆盖)改不了二进制与静态产物
|
|
COPY --from=ffprobe --chown=root:root --chmod=0555 /ffprobe /usr/local/bin/ffprobe
|
|
COPY --from=build --chown=root:root --chmod=0555 /src/dist/umt-server /app/umt-server
|
|
COPY --from=build --chown=root:root /src/apps/web/build/client /app/public
|
|
COPY --chown=root:root --chmod=0555 docker/entrypoint.sh /app/entrypoint.sh
|
|
COPY --chown=root:root --chmod=0555 scripts/backup.sh scripts/restore.sh /app/scripts/
|
|
RUN ln -s /app/entrypoint.sh /usr/local/bin/umt
|
|
ENV NODE_ENV=production \
|
|
HOST=0.0.0.0 \
|
|
PORT=4380 \
|
|
WEB_ROOT=/app/public \
|
|
DATA_DIR=/data \
|
|
PUID=10001 \
|
|
PGID=10001
|
|
# 以 root 启动只为修 /data 属主,entrypoint 随即 gosu 降权;api/worker/备份脚本都不以 root 运行
|
|
VOLUME ["/data"]
|
|
EXPOSE 4380
|
|
# 用二进制自带的 fetch 打本机回环端口,不装 curl
|
|
HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=3 CMD ["/app/umt-server", "--role", "probe"]
|
|
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
CMD ["serve"]
|