diff --git a/Dockerfile b/Dockerfile index 3ed9f101..32390401 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,62 @@ -FROM golang:1.17-alpine as cloudreve_builder - - -# install dependencies and build tools -RUN apk update && apk add --no-cache wget curl git yarn build-base gcc abuild binutils binutils-doc gcc-doc zip - -WORKDIR /cloudreve_builder -RUN git clone --recurse-submodules https://github.com/cloudreve/Cloudreve.git - -# build frontend -WORKDIR /cloudreve_builder/Cloudreve/assets -RUN yarn install --network-timeout 1000000 -RUN yarn run build && find . -name "*.map" -type f -delete - -# build backend -WORKDIR /cloudreve_builder/Cloudreve -RUN zip -r - assets/build >assets.zip -RUN tag_name=$(git describe --tags) \ - && export COMMIT_SHA=$(git rev-parse --short HEAD) \ - && go build -a -o cloudreve -ldflags " -X 'github.com/HFO4/cloudreve/pkg/conf.BackendVersion=$tag_name' -X 'github.com/HFO4/cloudreve/pkg/conf.LastCommit=$COMMIT_SHA'" - - -# build final image +# 多阶段构建: 编译发布物 +# 注意: 该阶段除最终发布物外不会影响最终镜像体积, 删除缓存、减少包安装等无意义 +FROM golang:1-alpine AS builder + +# 安装基本编译依赖 +RUN set -ex \ + && apk add build-base bash git yarn zip \ + && git clone --recursive https://github.com/cloudreve/Cloudreve.git /source + +# 编译前端代码 +WORKDIR /source/assets + +# 允许通过 `docker build --build-args YARN_REGISTRY=https://xxxx` 覆盖默认仓库地址 +ARG YARN_REGISTRY=https://registry.yarnpkg.com/ + +# 允许通过 `docker build --build-args GOPROXY=https://goproxy.cn` 添加 go mod 代理 +ARG GOPROXY="" + +# 暂不确定未来 alpine 内的 Node 版本是否影响最终编译结果, 故暂时增加打印输出 +RUN set -ex \ + && echo "Node Version: $(node -v)" \ + && sed -i -e "s@https://registry.yarnpkg.com/@${YARN_REGISTRY}@g" yarn.lock \ + && yarn install \ + && yarn run build \ + && find . -name "*.map" -type f -delete + +# 编译后端代码 +WORKDIR /source + +# assets.zip: 用于 go:embed 嵌入, 不可修改文件名 +RUN set -ex \ + && zip -r - assets/build > assets.zip \ + && go build -trimpath -o /cloudreve.bin -ldflags \ + "-w -s \ + -X github.com/cloudreve/Cloudreve/v3/pkg/conf.BackendVersion=$(git describe --tags) \ + -X github.com/cloudreve/Cloudreve/v3/pkg/conf.LastCommit=$(git rev-parse --short HEAD)" + +# 多阶段构建: 构建最终镜像 FROM alpine:latest -WORKDIR /cloudreve +RUN set -ex \ + && apk add --no-cache tzdata bash \ + && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && echo "Asia/Shanghai" > /etc/timezone -RUN apk update && apk add --no-cache tzdata +# 从编译阶段镜像复制可执行文件 +COPY --from=builder /cloudreve.bin /usr/bin/cloudreve -# we using the `Asia/Shanghai` timezone by default, you can do modification at your will -RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ - && echo "Asia/Shanghai" > /etc/timezone +# 复制启动脚本, 该脚本负责完成权限修复等预处理动作 +COPY docker-entrypoint.sh /docker-entrypoint.sh -COPY --from=cloudreve_builder /cloudreve_builder/Cloudreve/cloudreve ./ +# 默认文件存储位置 +VOLUME /data -# prepare permissions and aria2 dir -RUN chmod +x ./cloudreve && mkdir -p /data/aria2 && chmod -R 766 /data/aria2 +# 切换运行目录, 为未来可能的自动识别运行目录做准备 +WORKDIR /data -EXPOSE 5212 -VOLUME ["/cloudreve/uploads", "/cloudreve/avatar", "/data"] +# 镜像默认的开放端口, 它仅作为标识意义, 不干扰实际运行 +EXPOSE 5212/TCP -ENTRYPOINT ["./cloudreve"] \ No newline at end of file +# 除非使用明确的 entrypint 覆盖, 否则默认执行修复脚本并启动 +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 00000000..2726239e --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -e + +# 创建 aria2 共享目录 +mkdir -p /data/aria2 + +# 确保 aria2 可以被低权限用户写入 +chmod -R 766 /data/aria2 + +# 强制刷新二进制文件 +rm -f /data/bin +cp /usr/bin/cloudreve /data/.bin + +# 使用 exec 执行并拼接外部 CMD 指令参数 +exec /data/.bin $@