FROM rocker/r-ver:4.3 LABEL maintainer="dev-team@aiclinicalresearch.com" LABEL version="1.0.1" LABEL description="SSA-Pro R Statistics Service" # 安装系统依赖(包括 R 包编译所需的库) RUN apt-get update && apt-get install -y \ libcurl4-openssl-dev \ libssl-dev \ libxml2-dev \ libsodium-dev \ zlib1g-dev \ libnlopt-dev \ liblapack-dev \ libblas-dev \ gfortran \ pkg-config \ cmake \ curl \ && rm -rf /var/lib/apt/lists/* # 直接安装 R 包(简化方案,避免 renv 版本冲突) RUN R -e "install.packages(c( \ 'plumber', \ 'jsonlite', \ 'ggplot2', \ 'glue', \ 'dplyr', \ 'tidyr', \ 'base64enc', \ 'yaml', \ 'car', \ 'httr', \ 'scales', \ 'gridExtra', \ 'gtsummary', \ 'gt', \ 'broom', \ 'meta' \ ), repos='https://cloud.r-project.org/', Ncpus=2)" # 构建期校验:关键包缺失则直接失败,阻止坏镜像发布 RUN R -e "required <- c('plumber','jsonlite','ggplot2','glue','dplyr','tidyr','base64enc','yaml','car','httr','scales','gridExtra','gtsummary','gt','broom','meta'); installed <- rownames(installed.packages()); missing <- setdiff(required, installed); if (length(missing) > 0) { stop(paste('Missing required R packages:', paste(missing, collapse=', '))) } else { cat('All required R packages installed.\\n') }" # ===== 安全加固:创建非特权用户 ===== RUN useradd -m -s /bin/bash appuser WORKDIR /app # 复制应用代码 COPY plumber.R plumber.R COPY utils/ utils/ COPY tools/ tools/ COPY tests/ tests/ # 设置目录权限 RUN chown -R appuser:appuser /app # ===== 切换到非特权用户 ===== USER appuser EXPOSE 8080 # 环境变量 ENV DEV_MODE="false" # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 # 启动服务(不清理 /tmp,避免权限问题) CMD ["R", "-e", "plumber::plumb('plumber.R')$run(host='0.0.0.0', port=8080)"]