当前位置: 首页 > news >正文

Docker多容器通过卷共享 R 包目录

一、问题

       现在我有一台ubuntu服务器,上面运行了多个docker容器,其中有一个容器是flask后端,其需要执行R脚本,因此需要一个R环境,但是我希望这个R环境不要和宿主机的R环境混淆,现在我可以把flask后端的R环境用另一个R容器生成和管理,然后把R容器的包安装目录映射到宿主机指定目录,最后flask后端容器再把R包目录,挂载到flask后端容器中 ,实现R包共享。

二、 实现方案

  • R 容器:负责初始化 R 环境、安装所需 R 包,将 R 包目录(默认 /usr/local/lib/R/site-library)映射到宿主机共享目录;

  • Flask 容器:不直接安装 R,而是通过挂载宿主机的共享目录,复用 R 容器已安装的 R 包,仅需在容器内安装 R 解释器(无需重复装包);

  • 关键逻辑:R 包默认安装在 /usr/local/lib/R/site-library,只要让 Flask 容器的 R 解释器 “找到” 这个目录(通过挂载共享目录到相同路径),即可复用所有包,避免重复安装和环境混淆。

三、详细步骤

1. 宿主机准备:创建共享目录(用于映射 R 包)

  先在宿主机创建一个目录,用于存储 R 容器的包环境(后续 Flask 容器也挂载此目录):

# 宿主机执行:创建共享目录(路径可自定义,示例为 /data/r-packages)
mkdir -p /docker/R/4.3.1/packages
# 设置权限(避免容器内权限不足)
sudo chown $USER:docker /docker/R/4.3.1/packages  # 赋予当前用户和 docker 组权限
chmod 775 /docker/R/4.3.1/packages # 读写权限

2. 启动 R 容器:初始化 R 环境并安装包

      启动一个 R 容器,将 R 包目录 /usr/local/lib/R/site-library 映射到宿主机的 /docker/R/4.3.1/packages,并在 R 容器中安装所需包(如 ggplot2dplyr 等 Flask 脚本需要的包)。

docker run -it  --name R_4.3.1 --restart=always  -v /docker/R/4.3.1/packages:/usr/local/lib/R/site-library r-base:4.3.1 /bin/bash

       进入 R 容器的 bash 后,启动 R 并安装包(示例安装 ggplot2 和 dplyr,根据你的 Flask 脚本需求替换)

# 容器内执行:启动 R
R# 在 R 终端中安装包(安装路径会自动指向 /usr/local/lib/R/site-library,即宿主机的 /data/r-packages)
install.packages(c("ggplot2", "dplyr", "jsonlite"), dependencies = TRUE)  # 替换为你的需求包# 验证包安装:查看包路径是否在共享目录
.libPaths()  # 输出应包含 "/usr/local/lib/R/site-library"
q()  # 退出 R# 退出 R 容器(容器会停止,后续可重启复用)
exit

     回到宿主机,查看 /docker/R/4.3.1/packages是否有安装的 R 包(如 ggplot2 目录),确认映射生效。

3. 配置 Flask 容器:复用 R 包目录

Flask 容器需要满足两个核心条件:

  1. 容器内安装 R 解释器(仅需解释器,无需装包);

  2. 将宿主机的 /data/r-packages 挂载到 Flask 容器的 /usr/local/lib/R/site-library,让 R 解释器找到已安装的包。

基于现有 Flask 镜像改造:如果已有 Flask 容器镜像,只需在启动时添加 R 解释器安装和目录挂载。以 python:3.10-slim 基础镜像为例,编写 Dockerfile

# Flask 容器的 Dockerfile
FROM python:3.10-slim# 1. 安装 R 解释器(仅需解释器,不装包)
RUN apt-get update && apt-get install -y --no-install-recommends \r-base \  # 安装 R 解释器(轻量,不含额外包)&& rm -rf /var/lib/apt/lists/*  # 清理缓存,减小镜像体积# 2. 安装 Flask 依赖(根据你的项目需求调整)
COPY requirements.txt /app/
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt# 3. 复制 Flask 代码(根据你的项目路径调整)
COPY . /app# 4. 暴露 Flask 端口(如 5000)
EXPOSE 5000# 5. 启动 Flask 服务(根据你的启动命令调整)
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

4. Flask 脚本调用 R 脚本(关键:指定 R 路径)

       Flask 容器内的 R 解释器默认路径为 /usr/bin/R,在 Flask 脚本中通过 subprocess 等模块调用 R 脚本时,需指定正确的 R 路径,并确保 R 脚本能找到包(因包目录已挂载,无需额外配置)。

from flask import Flask
import subprocess
import osapp = Flask(__name__)# 定义调用 R 脚本的函数
def run_r_script(script_path):# R 解释器路径(Flask 容器内默认路径)r_path = "/usr/bin/R"# 构造 R 命令:执行脚本(--vanilla 避免加载无关配置)cmd = [r_path,"--vanilla",  # 纯净模式,避免干扰"-e", f"source('{script_path}')"  # 执行 R 脚本]# 执行命令并捕获输出result = subprocess.run(cmd,capture_output=True,text=True,cwd=os.path.dirname(script_path)  # 脚本所在目录)# 返回结果(成功/失败)if result.returncode == 0:return {"status": "success", "output": result.stdout}else:return {"status": "error", "error": result.stderr}# Flask 接口:调用 R 脚本
@app.route("/run-r-script")
def run_r():# R 脚本路径(Flask 容器内的路径,可挂载宿主机脚本目录)r_script_path = "/app/scripts/your_script.R"  # 示例路径,需与实际匹配result = run_r_script(r_script_path)return resultif __name__ == "__main__":app.run(host="0.0.0.0", port=5000, debug=True)

若后续需要更新 R 包,只需重启 R 容器,在容器内重新安装包(共享目录会自动同步更新),Flask 容器无需重启即可使用新版本包。

四、实际项目

1.Falsk程序dockerfile划分为两个部分:R和Python

R dockerfile:

FROM rocker/tidyverse:4.3.1# 1. 安装系统依赖(R 包编译所需,与 Flask 容器保持一致)
RUN apt-get update && apt-get install -y --no-install-recommends \libgsl27 libgsl-dev \libglpk40 libglpk-dev \&& rm -rf /var/lib/apt/lists/*# 2. 复制 R 包安装脚本到容器
COPY install_packages.R /tmp/install_packages.R# 3. 执行 R 包安装脚本(记录日志,方便调试)
RUN Rscript /tmp/install_packages.R > /tmp/install_packages.log 2>&1# 4. 先启动 bash,再用 tail 保持容器运行
CMD ["bash", "-c", "bash && tail -f /dev/null"]

Python dockerfile:

FROM rocker/tidyverse:4.3.1# 1. 安装 Python 环境(指定 3.9 版本)
RUN apt-get update && apt-get install -y --no-install-recommends \python3.9 \python3.9-dev \python3-pip \vim \&& rm -rf /var/lib/apt/lists/* \&& update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1 \&& update-alternatives --set python3 /usr/bin/python3.9# 2. 配置 Python 镜像源(清华源,加速安装)
RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple# 3. 设置工作目录
WORKDIR /app# 4. 创建日志目录并设置权限
RUN mkdir -p /var/log/glyseer && chmod 777 /var/log/glyseer  # 确保可写# 5. 复制 Python 依赖文件并安装
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt# 6. 复制 Flask 应用代码
COPY . .# 7. 暴露 Flask 服务端口
EXPOSE 8000# 8. 启动 Flask 服务(使用 gunicorn,配置合理参数)
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000", "-w", "4", "--timeout", "90"]

这样做的目的是保证R容器和flask容器系统环境一致!!!

2.启动R环境的docker容器

# 让 Docker 自动管理卷,容器内安装的 R 包会自动同步到卷中,且不会被空目录覆盖:
docker volume create r-packages-volume# 启动容器
docker run --name R_4.3.1 -d  --restart=always  -v r-packages-volume:/usr/local/lib/R/site-library glyseer_backend_r_base:1.0

http://www.dtcms.com/a/390666.html

相关文章:

  • 【保姆级教程】MasterGo MCP + Cursor 一键实现 UI 设计稿还原
  • Unity 性能优化 之 理论基础 (Culling剔除 | Simplization简化 | Batching合批)
  • react+andDesign+vite+ts从零搭建后台管理系统
  • No007:构建生态通道——如何让DeepSeek更贴近生产与生活的真实需求
  • 力扣Hot100--206.反转链表
  • Java 生态监控体系实战:Prometheus+Grafana+SkyWalking 整合全指南(三)
  • 生活琐记(3)
  • 在 Elasticsearch 和 GCP 上的混合搜索和语义重排序
  • 借助Aspose.HTML控件,使用 Python 将 HTML 转换为 DOCX
  • 设计测试用例的万能公式
  • 黑马头条_SpringCloud项目阶段三:HTML文件生成以及素材文章CRUD
  • 精准模拟,实战赋能-比亚迪秦EV整车检测与诊断仿真实训系统
  • 学习路之PHP--生成测试数据:fakerphp的使用
  • 《UE5_C++多人TPS完整教程》学习笔记54 ——《P55 旋转根骨骼(Rotate Root Bone)》
  • go资深之路笔记(五)用系统信号实现优雅关机
  • C++实战㉔】解锁C++ STL魔法:list与deque实战秘籍
  • Linux 系统指令——助力信奥初赛
  • LVS详解:构建高性能Linux负载均衡集群
  • 【Linux网络编程】网络层协议-----IP协议
  • 电池AH的定义与WH关系
  • 谙流 ASK 技术解析(四):负载均衡引擎
  • 乾元通渠道商中标国家华中区域应急救援中心应急救援装备采购项目
  • 网络原理补充——NAT/NAPT、代理服务、内网穿透、交换机
  • 深入 HTTP 协议:剖析 1688 商品详情 API 的请求构造与签名机制
  • 共用体union和大小端模式
  • 2022年下半年 系统架构设计师 案例分析
  • LeetCode 面试经典 150_哈希表_有效的字母异位词(42_242_C++_简单)
  • go webrtc - 3 工程演示
  • JVM(五)-- 执行引擎
  • 微算法科技(NASDAQ:MLGO)量子架构搜索技术:突破变分量子算法性能瓶颈,实现量子计算的鲁棒优化