You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统下Docker容器内Shiny应用连接外部MySQL数据库配置咨询

问题核心原因

你的app.R中数据库连接的host配置为localhost,受Docker网络隔离特性限制,容器内的localhost指向容器本身而非外部运行的MySQL服务,因此无法建立连接。


1 调整app.R配置

建议通过环境变量传入数据库配置,避免硬编码敏感信息,同时方便部署时灵活修改:

## libraries
library(tidyverse)
library(shiny)
library(shinydashboard)
library(ggplot2)
library(DBI)
library(RMySQL)

# shiny dashboard UI
ui <- dashboardPage(
    dashboardHeader(),
    dashboardSidebar(),
    dashboardBody(
        fluidPage(
            plotOutput("plot1")
        )
    )
)

# shiny dashboard server
server <- function(input, output,session) {
    # 从环境变量读取数据库配置,默认值可保留本地调试用
    db_host <- Sys.getenv("DB_HOST", "localhost")
    db_user <- Sys.getenv("DB_USER", "root")
    db_pwd <- Sys.getenv("DB_PWD", "#####")
    db_name <- Sys.getenv("DB_NAME", "Archenar")
    db_port <- as.integer(Sys.getenv("DB_PORT", 3306))
    
    #connection to database  
    orders <- dbConnect(RMySQL::MySQL(), 
                        user = db_user, 
                        password = db_pwd, 
                        dbname = db_name,
                        host = db_host,
                        port = db_port)
    
    # 新增:会话结束自动断开连接,避免连接泄漏
    session$onSessionEnded(function() {
        dbDisconnect(orders)
    })
    
    # 优化:checkFunc无需每次查询全表,用count减少资源消耗
    rigel <- reactivePoll(5000, session,checkFunc = function() {
        query2= "SELECT count(*) FROM SENSOR"
        rs = dbSendQuery(orders,query2)
        dbFetch(rs)
    },
    
    valueFunc = function() {
        query2= "SELECT * FROM SENSOR"  
        rs = dbSendQuery(orders,query2)
        dbFetch(rs)
    }
    )

    #make plot  
    output$plot1 <- renderPlot({
        rigelp <- rigel() %>% as.data.frame()%>% group_by(category) %>% 
            summarize(v=sum(value1))
        ggplot(rigelp,aes(x=category,y=v)) + geom_bar(stat = "identity")
        
    })  
}

shinyApp(ui, server)

2 调整Docker相关配置

2.1 优化Dockerfile(可选)

你当前的Dockerfile依赖已满足需求,可将分散的R包安装命令合并,减少镜像层数:

# get shiny server plus tidyverse packages image
FROM rocker/shiny:latest
# system libraries of general use
RUN apt-get update && apt-get install -y \
    sudo \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libmariadbd-dev \
    libxt-dev \
    libssl-dev \
    libssh2-1-dev
# 合并R包安装命令
RUN R -e "install.packages(c('shiny','tidyverse','shinydashboard','DBI','RMySQL'),repos='http://cran.rstudio.com/')"
# Copy configuration files into the Docker image
COPY shiny-server.conf  /etc/shiny-server/shiny-server.conf
COPY /app /srv/shiny-server/
RUN rm /srv/shiny-server/index.html
# 注意:与shiny-server.conf中监听端口保持一致,当前配置监听80,这里对应EXPOSE 80
EXPOSE 80
# Copy further configuration files into the Docker image
COPY shiny-server.sh /usr/bin/shiny-server.sh
RUN ["chmod", "+x", "/usr/bin/shiny-server.sh"]
CMD ["/usr/bin/shiny-server.sh"]

2.2 启动容器时传入数据库配置

启动容器时通过环境变量传入实际的MySQL连接信息,根据你的MySQL部署位置选择对应配置:

  • 如果MySQL部署在运行Docker的Ubuntu宿主机上:建议将DB_HOST设为宿主机的局域网IP,或添加--net=host参数直接使用宿主机网络
  • 如果MySQL是云数据库服务:直接将DB_HOST设为数据库的公网/内网连接地址,同时提前将云服务器IP加入数据库访问白名单

示例启动命令:

docker run -d -p 宿主机端口:80 \
  -e DB_HOST=你的MySQL服务实际IP地址 \
  -e DB_USER=数据库用户名 \
  -e DB_PWD=数据库密码 \
  -e DB_NAME=Archenar \
  你构建的Shiny镜像名称

3 常见问题排查
  1. 先确认MySQL服务正常运行,3306端口未被防火墙拦截
  2. 确认数据库用户允许你配置的IP访问,不要仅限制localhost登录
  3. 可进入容器内部测试网络连通性:执行docker exec -it 容器ID bash进入容器,安装mysql-client后手动尝试连接数据库,先排除网络问题再排查代码问题

内容的提问来源于stack exchange,提问作者Jonathan Livingston Seagull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:00:00