在容器中执行脚本，被killed。大概猜想是内存不够，本机是16G、docker限制8G。查看日志#查看当前 Docker 使用的 WSL 发行版 wsl -l -v #进入 docker 的 WSL 宿主机（一般是 docker-desktop） wsl -d docker-desktop #查看 dmesg 日志（内核日志） dmesg | grep -i kill # 或者 dmesg -T | grep -i "killed process"果真，那就修改一下内存限制再试试吧。修改wsl2限制内存定位到你的 用户目录（比如 C:Users你的用户名）（可以win + r 输入 %UserProfile% ）,打开用户目录，创建.wslconfig文件。C:Users<你的用户名>.wslconfig添加或修改以下内容：[wsl2] memory=12GB swap=4G processors=6memory=12GB # 分配给 WSL2 的最大内存processors=6 # 可选，限制使用的 CPU 核心数swap=8GB # 可选，设置 swap 大小保存后，重启 WSLwsl --shutdown重启 Docker Desktop。修改之前修改之后虽然还是没什么卵用，去线上跑吧。垃圾
docker-R语言多版本安装，在python中使用R容器执行脚本
.env# 新增R版本 4.2.1 R_NAME_421=r_4_2_1 # 容器/镜像 名称 R_VERSION_421=4.2.1 # 版本号 R_PORT_421=8780 # 新增R版本 4.3.0 R_NAME_430=r_4_3_0 R_VERSION_430=4.3.0 R_PORT_430=8781 # 新增R版本 4.4.2 R_NAME_442=r_4_4_2 R_VERSION_442=4.4.2 R_PORT_442=8782docker-compose.yml # R 服务 4.2.1 r_4_2_1: build: context: . dockerfile: ${R_DOCKERFILE} # dockerfile公共文件 args: FROM_IMAGE: rocker/r-ver:${R_VERSION_421} # 指定镜像版本 R_BIOC_MIRROR: ${R_BIOC_MIRROR} # 公共 镜像源 R_CRAN: ${R_CRAN} container_name: ${R_NAME_421} # 指定版本名称 image: ${R_NAME_421}-image # 指定镜像名称 ports: - "${R_PORT_421}:${R_PORT_421}" # 指定端口 volumes: - ./R:/workspace/R - ./static/matrix:/workspace/static/matrix - .env:/workspace/.env # 挂载 .env 文件 #- ./store/docker/r-library/${R_NAME_442}:/usr/local/lib/R/site-library # 持久化 R 包的安装位置 environment: - R_HOME=/usr/local/lib/R command: Rscript R/http/start.R # 启动API服务 restart: unless-stopped networks: - backend # R 服务 4.3.0 r_4_3_0: build: context: . dockerfile: ${R_DOCKERFILE} # dockerfile公共文件 args: FROM_IMAGE: rocker/r-ver:${R_VERSION_430} # 指定镜像版本 R_BIOC_MIRROR: ${R_BIOC_MIRROR} # 公共 镜像源 R_CRAN: ${R_CRAN} container_name: ${R_NAME_430} # 指定版本名称 image: ${R_NAME_430}-image # 指定镜像名称 ports: - "${R_PORT_430}:${R_PORT_430}" # 指定端口 volumes: - ./R:/workspace/R - ./static/matrix:/workspace/static/matrix - .env:/workspace/.env # 挂载 .env 文件 #- ./store/docker/r-library/${R_NAME_430}:/usr/local/lib/R/site-library # 持久化 R 包的安装位置 environment: - R_HOME=/usr/local/lib/R command: Rscript R/http/start.R # 启动API服务 restart: unless-stopped networks: - backend # R 服务 4.4.2 r_4_4_2: build: context: . dockerfile: ${R_DOCKERFILE} # dockerfile公共文件 args: FROM_IMAGE: rocker/r-ver:${R_VERSION_442} # 指定镜像版本 R_BIOC_MIRROR: ${R_BIOC_MIRROR} # 公共 镜像源 R_CRAN: ${R_CRAN} container_name: ${R_NAME_442} # 指定版本名称 image: ${R_NAME_442}-image # 指定镜像名称 ports: - "${R_PORT_442}:${R_PORT_442}" # 指定端口 volumes: - ./R:/workspace/R - ./static/matrix:/workspace/static/matrix - .env:/workspace/.env # 挂载 .env 文件 #- ./store/docker/r-library/${R_VERSION_442}:/usr/local/lib/R/site-library # 持久化 R 包的安装位置 environment: - R_HOME=/usr/local/lib/R command: Rscript R/http/start.R # 启动API服务 restart: unless-stopped networks: - backend dockerfileARG FROM_IMAGE=rocker/r-ver:4.4.1 FROM ${FROM_IMAGE} ARG R_BIOC_MIRROR=https://mirrors.tuna.tsinghua.edu.cn/bioconductor ARG R_CRAN=https://mirrors.tuna.tsinghua.edu.cn/CRAN/ # 设置镜像源为清华大学的 CRAN 镜像和 Bioconductor 镜像 RUN echo "options(BioC_mirror = '${R_BIOC_MIRROR}')" >> /usr/local/lib/R/etc/Rprofile.site RUN echo "options(repos = c(CRAN = '${R_CRAN}'))" >> /usr/local/lib/R/etc/Rprofile.site ## 安装系统依赖包 RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu/|' /etc/apt/sources.list && \ apt-get update && \ apt-get install -y \ libcurl4-openssl-dev \ libssl-dev \ libxml2-dev \ libfontconfig1-dev \ libharfbuzz-dev \ libfribidi-dev \ libpango1.0-dev \ libx11-dev \ libxt-dev \ libjpeg-dev \ libpng-dev \ libtiff-dev \ libbz2-dev \ libsodium-dev \ && rm -rf /var/lib/apt/lists/* \ # 安装中文字体 RUN apt-get update && apt-get install -y fonts-wqy-zenhei fonts-wqy-microhei ttf-mscorefonts-installer fontconfig # 查看系统中的中文字体：fc-list :lang=zh # 报错：dpkg 进程被中断了； 修复：dpkg --configure -a ## 设定工作目录 WORKDIR /workspace ## 常用包安装脚本 COPY R/docker/install_packages.R /workspace/install_packages.R # 验证文件是否被成功复制 RUN ls -l /workspace/install_packages.R ## 执行(耗时) RUN Rscript /workspace/install_packages.R ## 设定工作目录 WORKDIR /workspace # ## 保持容器在后台运行 CMD ["tail", "-f", "/dev/null"] install_packages.R # 安装常用的包 install.packages('pheatmap') install.packages('BiocManager') options(timeout = 600) install_missing_packages <- function(packages) { if (!requireNamespace("BiocManager", quietly = TRUE)) { install.packages("BiocManager") } for (package in packages) { if (!requireNamespace(package, quietly = TRUE)) { cat(paste("开始安装", package, "...\n")) BiocManager::install(package, ask = FALSE) } else { cat(paste( packageVersion(package), package, "已安装.\n" )) } } } # 安装常用的包 packages <- c('GEOquery', 'ggplot2', 'readxl', 'readr', 'openxlsx', 'dplyr', 'clusterProfiler', 'limma', 'DESeq2', 'ggtree', 'org.Hs.eg.db','org.Mm.eg.db','org.Rn.eg.db','GOplot','stringr', 'enrichplot', 'treeio', 'WGCNA', 'igraph','plumber','jsonlite','dotenv','remotes') # 安装缺失的 R 包 install_missing_packages(packages) # 针对某个版本中的某些包进行检测安装 r_version <- getRversion() cat(paste("检测R版本", r_version , "...\n")) if(r_version == "4.2.1"){ if (!requireNamespace("ggtree", quietly = TRUE)) { remotes::install_github("YuLab-SMU/ggtree") } if (!requireNamespace("clusterProfiler", quietly = TRUE)) { remotes::install_github("ctlab/fgsea") BiocManager::install("clusterProfiler") } } if(r_version == "4.3.0"){ if (!requireNamespace("ggtree", quietly = TRUE) && !requireNamespace("limma", quietly = TRUE) && !requireNamespace("org.Hs.eg.db", quietly = TRUE) ) { options(BioC_mirror = "https://bioconductor.org") install_missing_packages(packages) } if (!requireNamespace("ggtree", quietly = TRUE)) { remotes::install_github("YuLab-SMU/ggtree") } if (!requireNamespace("clusterProfiler", quietly = TRUE)) { remotes::install_github("ctlab/fgsea") BiocManager::install("clusterProfiler") } } 如何在Python中使用R容器，执行R脚本？搭建好后可以通过接口的方式运行R脚本也可以使用py-docker操作容器（线上可能需要挂载docker守护进程）接口服务http.R if (!requireNamespace("plumber", quietly = TRUE)) { cat(paste("开始安装", "plumber", "...\n")) BiocManager::install("plumber", ask = FALSE) } if (!requireNamespace("jsonlite", quietly = TRUE)) { cat(paste("开始安装", "jsonlite", "...\n")) BiocManager::install("jsonlite", ask = FALSE) } if (!requireNamespace("dotenv", quietly = TRUE)) { cat(paste("开始安装", "dotenv", "...\n")) BiocManager::install("dotenv", ask = FALSE) } cat("当前工作目录",getwd(),"\n") # 加载 dotenv 包 library(dotenv) library(plumber) # 读取 .env 文件 load_dot_env(".env") #print(Sys.getenv()) # 获取 R 版本号 r_version <- getRversion() cat("R版本:", as.character(r_version), "\n") # 将 R 版本号转换为 .env 文件中的键名格式 例如：4.2.1 -> 421 r_version_key <- gsub("\\.", "", as.character(r_version)) # 构建端口号的键名 port_key <- paste0("R_PORT_", r_version_key) # 从 .env 文件中获取端口号 port <- as.integer(Sys.getenv(port_key)) if (is.na(port)) { # 如果端口号不存在，使用默认端口 port <- 8006 # 默认端口 warning("未找到当前R版本的端口配置(",port_key,") 使用默认端口：", port) }else{ cat("找到当前 R 版本的端口配置：", port, "\n") } # 创建 plumber API pr <- plumb("R/http/app.R") # 启动 plumber 服务 pr$run(host = "0.0.0.0", port = port) app.Rlibrary(jsonlite) # 定义一个 API 端点，执行 R 脚本 #* 执行 R 脚本 #* @post /run_r_script function(req, script = "", param = "") { # 调用执行脚本的函数 result <- run_script(script, param) return(result) } #* 执行系统命令 post #* @post /run_command function(req, command = "") { if (command == "") { return(list(code = unbox(0),msg = unbox("未提供命令") )) } # 执行系统命令 result <- tryCatch({ output <- system(command, intern = TRUE) list(code = unbox(1), msg = unbox("命令执行成功"), data = output) }, error = function(e) { list(code = unbox(0), msg = unbox(e$message) ) }) return(result) } # 执行 R 脚本的函数 run_script <- function(script_path, params) { setwd("/workspace") # 检查脚本文件是否存在 if (!file.exists(script_path)) { return( list( code = unbox(0), msg = unbox("脚本文件不存在"), data = getwd() )) } # 将参数转换为 R 对象 #params <- jsonlite::fromJSON(params) # 构造命令行 command <- paste("Rscript", script_path, shQuote(params)) # 在独立环境中执行脚本 result <- tryCatch({ #run_result <- source(script_path) # 执行结果 run_result <- system(command, intern = TRUE) print(run_result) # 获取退出状态 exit_status <- attr(run_result, "status") exit_status <- ifelse(is.null(exit_status), 0, exit_status) print(cat("退出状态：",exit_status,"\n")) if(exit_status == 1){ # 将 run_result 转换为字符串 result_string <- paste(run_result, collapse = "\n") #print(result_string) list( code = unbox(0), # 使用 unbox() 将 code 转换为标量值 msg = unbox(result_string), data = run_result, # 捕获的输出 output = params ) }else{ #run_result <- capture.output(source(script_path)) list( code = unbox(1), # 使用 unbox() 将 code 转换为标量值 msg = unbox("脚本执行成功"), data = run_result, # 捕获的输出 output = params ) } }, error = function(e) { print(e) list( code = unbox(0), msg = unbox("脚本执行失败"), data = NULL, output = unbox(e$message) ) }) return(result) }
version: '3.8' services: # FastAPI 服务 fastapi: build: context: . dockerfile: Dockerfile container_name: ${FASTAPI_CONTAINER_NAME} image: ${FASTAPI_IMAGE} # 启动web服务和队列 command: /bin/bash -c "uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4 & arq main_queue.WorkerSettings" ports: - "${FASTAPI_PORT}:8000" # depends_on: # - redis volumes: - .:/app networks: - backend # 加入一个外部网络，比如 dnmp_default 下有redis、mysql，可以直接通过 容器名称:内部端口 访问。 - dnmp_default networks: backend: driver: bridge dnmp_default: # 声明外部网络 external: true
Tomcatdocker run -d -p 8080:8080 --name=mytomcat8 billygoo/tomcat8-jdk8运行起来后，访问 127.0.0.1:8080{dotted startColor="#ff6c6c" endColor="#1989fa"/}Mysql查看服务器本身是否存在mysql占用3306端口ps -ef|grep mysql安装运行mysql 并挂载数据卷{message type="error" content="错误运行。 不能使用这个！！没有做数据挂载"/}# docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7{message type="success" content="正确的运行方式。 实现数据同步备份，就算容器被删除了，重新执行这段命令也会自动恢复"/}/* docker run -d -p 3306:3306 --privileged=true -v /xx/mysql/log:/var/log/mysql -v /xx/mysql/data:/var/lib/mysql -v /xx/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7 */ docker run -d -p 3306:3306 --privileged=true -v /tmp/host_data/mysql/log:/var/log/mysql -v /tmp/host_data/mysql/data:/var/lib/mysql -v /tmp/host_data/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7配置Mysql如果不配置，插入中文可能会乱码# 进入配置文件，利用数据库同步完成配置 cd /tmp/host_data/mysql/conf # 新建my.cnf vim my.cnf #插入以下配置 （按i进入编辑，esc + :wq 保存退出） [client] default_character_set=utf8 [mysqld] collation_server=utf8_general_ci character_set_server=utf8 #查看配置 cat my.cnf #重启mysql docker restart eb0a5548b284 mysql操作#查看是否运行起来 docker ps #进入容器 docker exec -it d1669c7cf3e0 /bin/bash #进入mysql mysql -uroot -p #>>>输入上面设置的密码 123456 # 接下来就可以操作mysql了 #列出所有数据库 show databases; #创建一个数据库 create database db1; #在db1库中创建一张表 use db1; create table t1(id int,name varchar(20)); #操作数据... insert into t1 values(1,'zs'); #需要进行配置，不然插入中文会报错 insert into t1 values(2,'张三'); select * from t1; 在本连接docker中的mysql使用ifconfig查看ipip+3306 ，root +123456(刚刚设置的密码） 连接连接成功数据存在{dotted startColor="#ff6c6c" endColor="#1989fa"/}
数据卷容器数据与宿主机目录 进行映射容器数据卷的方式完成持久化，对重要资料备份特点可以在容器之间共享和重用数据卷中的修改可以直接实时生效数据卷中的修改不会包含在镜像的更新中数据卷的生命周期一直持续到没有容器使用它为止容器停止了也会自动同步宿主机绑定目录内的数据命令#docker run -it --privileged=true -v /宿主机绝对目录:/容器内目录 镜像名 # -v可以绑定多个 # --privileged=true #给权限 docker run -it --privileged=true -v /tmp/host_data:/tmp_docker --name=u1 ubuntu #在docker中创建一个文件 也会同步到宿主机 #>>>docker # 进入挂载的目录 tmp_docker cd /tmp_docker # 创建一个txt文件 touch dockerin.txt # 查看文件是否创建成功 ls #回到宿主机(本地主机) #>>>host # 进入绑定的目录 cd /tmp/host_data # 查看文件列表 ls #>>> 会出现刚刚在docker中创建的 dockerin.txt # 在本地主机创建文件，也会自动同步到docker目录 # 其他 # 容器内只读 docker run -it --privileged=true -v /tmp/host_data:/tmp_docker:ro --name=u1 ubuntu #查看容器列表 docker ps # 查看docker信息（挂载目录） docker inspect 6da5cb04fc6继承容器卷之间数据共享·会继承父类的挂载规则，并且数据与 宿主机、父类、当前镜像 同步·父类停止,也会同步数据#docker run -it --privileged=true --volumes-from 父类 --name=u2 ubuntu docker run -it --privileged=true --volumes-from u1 --name=u2 ubuntu
容器 操作命令#查看容器列表 docker ps #其他 docker ps -a # 列出当前正在运行的容器+历史运行过的容器 docker ps -l # 列出最近创建的容器 docker ps -n 3 # 显示最近创建的3个容器 docker ps -q # 只显示容器ID # 查看命令帮助 docker run --help #-d 后台运行并返回容器ID #-it 以交互模式运行，并返回一个伪终端 #--name="容器的名称" 为容器指定一个新的名称 #-P 随机端口映射 #-p 指定端口映射 docker run -d -p 6379:6379 redis:6.0.8 docker run -it ubuntu /bin/bash docker run -it 镜像ID /bin/bash # 指定名称 docker run -it --name=myu1 ubuntu /bin/bash # 启动容器 docker start 容器ID或名称 # 停止容器 docker stop 容器ID或名称 # 强制停止容器 docker kill 容器ID或名称 #删除容器 #rm 移除一个或多个容器 docker rm -f 容器ID docker rm -f 容器ID,容器ID,容器ID docker rm -f $(docker ps -a -q) # restart 重启运行的容器 # rm -f 强制移除一个或多个容器 # tag 给源中镜像打标签 # version 查看docker版本号 exit # 停止容器、退出容器交互 #按住 ctrl+p+q #退出，不停止容器 # commit 提交容器副本使之成为一个新的镜像 # docker commit -m="这是一个新的" -a="作者" 容器ID 包/镜像名:版本号 docker commit -m="这是一个新的" -a="作者" abc en/ubuntu:1.3 镜像 操作命令#查看镜像列表 docker image ls docker images # 查看 镜像/容器/数据卷 占用的空间 docker system df # 搜索镜像 docker search 镜像名 # 从docker镜像源服务器拉取指定镜像或库镜像 docker pull 镜像名 # push 推送指定镜像或库镜像到docker源服务器 docker pull ubuntu # 移除一个或多个镜像 docker rmi 镜像ID #强制移除一个或多个镜像(正在运行的) docker rmi -f 镜像ID 交互式和守护式#守护式 后台运行 docker -d xxx #交互式 运行后进入该容器的终端 docker -it xxx #exit 停止容器、退出容器交互 #ctrl+p+q 退出，不停止容器运行镜像（以redis为例）#run 表示 创建一个新的容器并运行 # -d 表示 后台运行 # redis:6.0.8 表示 redis:版本 docker run -d redis:6.0.8 # redis-cli -p 6379 # ping # set k1 123 # get k1容器# 查看容器日志 # 684d2d24b569 表示 容器ID ( 使用 docker ps 命令查看ID ) docker logs 684d2d24b569 #查看容器内运行的进程 docder top 684d2d24b569 #查看容器内部细节 docker inspect 684d2d24b569 #重新进入正在运行的容器 并且以命令交互 #exec 是在容器中打开新的终端，启用新的进程。用exit退出不会导致容器停止 docker exec -it 684d2d24b569 /bin/bash #attach 直接进入启动命令的终端，不会启用新的进程。用exit退出会导致容器停止 docker attach 684d2d24b569 #把容器内的文件拷贝到主机(本地)上 docker cp 容器ID:容器内路径 目的主机路径 #导出 将容器导出为tar文件 docker export 容器ID > abc.tar #导入 从tar包中的内容创建一个新的文件系统 导入为镜像 cat abc.tar | docker import -镜像用户/镜像名:镜像版本号 上传到阿里云镜像仓库登录阿里云 -> 容器镜像服务/实例列表/镜像仓库/基本信息创建实例 - 设置密码 - 创建 命名空间和镜像仓库，进入管理测试修改一个ubuntu# 运行ubuntu docker run -it ubuntu /bin/bash # 安装vim apt-get update apt-get install vim vim a.txt #按i进入编辑 #...输入文字 #esc :wq 退出 # commit 将容器变成镜像 docker commit -m="这是一个新的" -a="作者" abc en/ubuntu:1.1 # 镜像列表 docker images推送#1.登录 docker login --username=阿里云账号 registry.cn-hangzhou.aliyuncs.com #>>>回车后需要输入密码 #2.设置标签 #docker tag [镜像ID] registry.cn-hangzhou.aliyuncs.com/ay/mtubuntu:[镜像版本号] docker tag 5555cd2a82d0 registry.cn-hangzhou.aliyuncs.com/ay/mtubuntu:1.1 #3.推送 docker push registry.cn-hangzhou.aliyuncs.com/ay/mtubuntu:1.1拉取#删除本地这个镜像 docker rmi -f 5555cd2a82d0 #拉取 #docker pull registry.cn-hangzhou.aliyuncs.com/ay/mtubuntu:[镜像版本号] docker pull registry.cn-hangzhou.aliyuncs.com/ay/mtubuntu:1.1 #运行 docker run -it 5555cd2a82d0 /bin/bash #查看vim命令是否可用 vim a.txt
创建一个文件夹 docker ，在这个文件夹中打开终端，执行git clone https://gitee.com/yeszao/dnmp.git进入项目目录cd dnmp 复制环境变量文件，如果要修改，在up之前修改cp env.sample .env复制 docker-compose 配置文件。默认启动3个服务：Nginx、PHP7和MySQL8。要开启更多其他服务，如Redis请删除服务块前的注释cp docker-compose.sample.yml docker-compose.yml创建并且启动所有容器docker-compose up安装完成访问 http://localhost/ ，出现下面截图表示安装完成。超级简单吧～映射docker/www/localhost/ 中的文件。{dotted startColor="#ff6c6c" endColor="#1989fa"/}安装php扩展1.进入php容器docker exec -it php /bin/sh安装swooleinstall-php-extensions swoole安装完成重启php容器安装redisinstall-php-extensions redis可能会出现一个错误DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user.进入 services/redis/redis.conf 把 protected-mode no 改成 protected-mode no {dotted startColor="#ff6c6c" endColor="#1989fa"/}{dotted startColor="#ff6c6c" endColor="#1989fa"/}在本地环境绑定一个自定义域名{hide}在 services/nginx/conf.d/ 创建一个文件 test.conf写入server { listen 80; server_name dnmp.t1.com; # 自定义域名 root /www/t1; # 对应的运行目录 】 index index.html index.htm index.php; client_max_body_size 500m; charset utf-8; keepalive_timeout 0; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ [^/]\.php(/|$) { fastcgi_pass php:9000; include fastcgi-php.conf; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }修改系统host文件，绑定域名打开 /etc/hosts 文件添加一行127.0.0.1 dnmp.t1.com保存！{/hide}