在Azure上部署ShinyProxy的问题及优化方案咨询
我正在研究如何在Azure上基于Docker部署ShinyProxy,希望以简单、可扩展且低成本的方式完成搭建。据我了解,在Azure上部署Docker基础服务共有5种方案。
咨询问题
我的问题主要分为两部分:
- 部署基于ShinyProxy的容器,实现根据用户连接会话自动创建、销毁其他容器的通用实践经验
- 如何修正我当前的部署方案以解决现存问题
已尝试的部署方案
(按优先级从高到低排序,除虚拟机方案外其余均已测试)
A) App Service Docker或Docker Compose部署
我对该方案最熟悉,底层复杂度已被平台封装
采用该方案时我发现,当前Azure App Service的Docker和Docker Compose实现不支持(会忽略)networks配置项,而该配置是ShinyProxy与内部网络中其他容器通信的必备条件。我在Docker Compose文件中编写了如下配置(已验证本地可正常运行):
networks: app_default: driver: bridge external: false name: app_default
根据我对文档的理解,App Service无法为容器创建自定义网络,目前也不清楚是否可以创建自定义Azure vnet来满足该需求(我没有vnet搭建相关经验)。
ShinyProxy部署的第二个核心要求是将宿主机与容器的docker.sock文件映射,该配置同样可以通过Docker Compose文件或单Docker文件参数实现,我在Docker Compose中编写的配置如下(已验证本地可正常运行):
volumes: # `//`路径前缀仅适用于Windows宿主机,原因是Windows使用Windows Pipeline系统适配这类Unix文件系统路径;Linux宿主机仅需使用单斜杠`/`作为前缀 # Windows宿主机卷配置 # docker_sock: //var/run/docker.sock # Linux宿主机卷配置 docker_sock: /var/run/docker.sock
随后使用docker_sock命名卷与容器内的/var/run/docker.sock文件映射:docker_sock:/var/run/docker.sock。
受上述两个问题影响,访问ShinyProxy的application.yml文件中定义的任意specs时,都会抛出Connection refused或File could not be foundJava错误,两类错误分别对应网络通信异常和docker.sock映射异常。
B) 容器实例(Container Instances)
新型服务,使用门槛较低
存在和App Service方案完全相同的问题。
C) 容器应用(Container Apps)
新型服务,使用门槛较低
存在和App Service方案完全相同的问题。
D) Kubernetes服务
需要大量额外配置
已尝试但最终放弃该方案,我不想额外处理K8s的配置层,且我的需求场景不需要这么高的可控性。
E) 虚拟机(Virtual Machine)
生产环境需要大量自行搭建和运维操作
尚未测试,目前已有多篇相关文章介绍该方案的实现方式。
本地复现方法
以下是我的配置文件修改示例,保留了若干注释和注释掉的配置项。
ShinyProxy application.yml:
# ShinyProxy Configuration proxy: title: ShinyProxy Apps landing-page: / heartbeat-enabled: true heartbeat-rate: 10000 # 10秒 heartbeat-timeout: 60000 # 60秒 # ShinyProxy等待容器就绪的超时时间 container-wait-time: 20000 # 20秒 port: 8080 authentication: none docker: # url: http://localhost:2375 privileged: true internal-networking: true container-network: "app_default" specs: - id: hello_demo container-image: openanalytics/shinyproxy-demo display-name: Hello Application description: 演示Shiny应用基础功能的示例程序 container-network: "${proxy.docker.container-network}" # container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"] logging: file: name: shinyproxy.log server: servlet: context=path: / sprint: application: name: "ShinyProxy Apps"
ShinyProxy Dockerfile:
FROM openjdk:8-jre USER root RUN mkdir -p "/opt/shinyproxy" # 从官方源下载对应版本的shinyproxy RUN wget https://www.shinyproxy.io/downloads/shinyproxy-2.6.0.jar -O "/opt/shinyproxy/shinyproxy.jar" # 也可以直接拷贝本地的shinyproxy jar包 # COPY shinyproxy.jar "/opt/shinyproxy/shinyproxy.jar" COPY application.yml "/opt/shinyproxy/application.yml" WORKDIR /opt/shinyproxy/ CMD ["java", "-jar", "/opt/shinyproxy/shinyproxy.jar"]
docker-compose.yml:
networks: app_default: driver: bridge external: false name: app_default # volumes: # `//`路径前缀仅适用于Windows宿主机,因为Windows使用Windows Pipeline系统适配这类Unix文件系统路径 # Linux宿主机仅需使用单斜杠`/`作为前缀 # Windows宿主机专属卷配置 # docker_sock: //var/run/docker.sock # Linux宿主机专属卷配置 # docker_sock: /var/run/docker.sock services: # 可以用来测试非shinyproxy的其他镜像 # hello_demo: # image: openanalytics/shinyproxy-demo # container_name: hello_demo # ports: # - 3838:3838 # networks: # - app_default # volumes: # - //var/run/docker.sock:/var/run/docker.sock shinyproxy: build: ./shinyproxy container_name: app_shinyproxy # 替换为你自己构建的镜像名称 image: shinyproxy:latest # privileged: true restart: OnFailure networks: - app_default ports: - 8080:8080 volumes: - //var/run/docker.sock:/var/run/docker.sock
所有文件准备完成后,执行docker compose build && docker compose up即可本地运行。
内容的提问来源于stack exchange,提问作者Adrian Z.

