Rstudio通过docker无法读取/etc/.odbc.ini文件,只能读取~/.odbc.ini文件。

4
当我构建并运行运行在Ubuntu上的rstudio的Docker容器时,如果我在构建期间添加odbc.ini文件,odbc连接将不起作用。然而,如果我在运行容器时从容器内部添加odbc.ini文件,则连接确实可以工作。
因此,我的问题是每当运行这个镜像时,我都希望能够直接启动odbc连接,而不需要登录到Ubuntu容器实例并向odbc.ini文件添加连接详细信息的额外步骤。
下面是odbc.ini文件的样例,其中包含虚拟数据:
[PostgreSQL ANSI]
    Driver              = PostgreSQL ANSI
    Database            = GoogleData
    Servername          = somename.postgres.database.azure.com
    UserName            = docker_rstudio@somename
    Password            = abc123abc
    Port                = 5432
    sslmode             = require

我在我的代码库目录下有一个odbc.ini文件的副本,并将其包含在构建中。这是我的DockerFile。

FROM rocker/tidyverse:3.6.3
ENV ADD=SHINY
ENV ROOT=TRUE
ENV PASSWORD='abc123'
RUN apt-get update && apt-get install -y \
   less \
   vim  \
   unixodbc unixodbc-dev \
   odbc-postgresql
ADD odbc.ini /etc/odbc.ini
ADD install_packages.R /tmp/install_packages.R
RUN Rscript /tmp/install_packages.R && rm -R /tmp/*
ADD flagship_ecommerce /home/rstudio/blah/zprojects/flagship_ecommerce
ADD commission_junction /home/rstudio/blah/zprojects/commission_junction
RUN mkdir /srv/shiny-server; ln -s /home/rstudio/blah/zprojects/ /srv/shiny-server/

如果我通过rstudio登录到实例,连接不起作用,我会收到以下错误消息:

Error: nanodbc/nanodbc.cpp:983: 00000: 无法连接到服务器: 没有这样的文件或目录 服务器正在本地运行并接受连接吗? 连接Unix域套接字“/var/run/postgresql/.s.PGSQL.5432”?

如果我使用less /etc/odbc.ini查看文件,确实可以看到与我的顶部代码块相符的连接详细信息。

如果我然后使用cp /etc/odbc.ini /home/rstudio/.odbc.ini将其复制到主目录,那么在此之后,我的连接确实可以工作。

但是,即使我使用ADD odbc.ini /home/rstudio/.odbc.ini修改了dockerfile,连接也不起作用。只有当我手动添加到/home/rstudio/.odbc.ini时,它才能工作。

所以我的问题有两个方面:

  1. 无论我尝试什么,我都不能使ubuntu检测到/etc/odbc.ini以用作odbc连接字符串。无论是通过Dockerfile还是手动添加。我希望这样做,因为我希望连接对使用容器的任何人都可用。

  2. 我能够手动将上面odbc.ini中的内容复制到/home/rstudio/.odbc.ini,但是如果我尝试通过docker构建来完成这个操作,则连接不起作用。我确实看到文件存在,并且包含所有正确的数据,它只是未被odbc检测到。

如果这方面有关联:

odbcinst -j
unixODBC 2.3.6
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/rstudio/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

1
这是权限问题吗?也许 https://stackoverflow.com/q/25293266/3358272 可以帮助。如果不是那个问题,请检查 /etc/odbc.ini~/.odbc.ini 的文件所有权,确保它们属于当前运行的用户(可以由 Dockerfile 定义)和/或模式 644。 - r2evans
2个回答

3

我认为问题在于你的 /etc/odbc.ini格式。虽然我没有你所有的脚本,但这是我使用的 Dockerfile

FROM rocker/tidyverse:3.6.3
ENV ADD=SHINY
ENV ROOT=TRUE
ENV PASSWORD='abc123'
RUN apt-get update && apt-get install -y \
   less \
   vim  \
   unixodbc unixodbc-dev \
   odbc-postgresql
RUN Rscript -e 'install.packages(c("DBI","odbc"))'
ADD ./odbc.ini /etc/odbc.ini

如果我使用这个样例的 odbc.ini

[mydb]
    Driver              = PostgreSQL ANSI
    ServerName          = 127.0.0.1
    UserName            = postgres
    Password            = mysecretpassword
    Port                = 35432

我看到这个(docker构建和R启动消息被截断):

$ docker build -t quux2 .
$ docker run --net='host' -it --rm quux2 bash
> con <- DBI::dbConnect(odbc::odbc(), "mydb")
Error: nanodbc/nanodbc.cpp:983: 00000: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

当我将文件的缩进更改为以下内容时:

[mydb]
Driver              = PostgreSQL ANSI
ServerName          = 127.0.0.1
UserName            = postgres
Password            = mysecretpassword
Port                = 35432

我看到这个:

$ docker build -t quux3 .
$ docker run --net='host' -it --rm quux3 bash
> con <- DBI::dbConnect(odbc::odbc(), "mydb")
> DBI::dbGetQuery(con, "select 1 as a")
  a
1 1

(为了演示,我在另一个容器中运行postgres:11,但我认为这并不相关,这是缩进的值。)

1
非常感谢!我真的不明白你是如何找出这是缩进问题的,但这确实解决了我的问题。 - Doug Fir
1
顺便问一下,您考虑过不要将 odbc.ini 文件打包到容器中,而是将其挂载为卷吗?我的前几次测试(此处未展示)都包括 -v ./odbc.ini:/etc/odbc.ini,结果也一样成功。在容器中嵌入密码最好是一个有问题的做法。 - r2evans
谢谢您的建议。我会向我们的DevOps团队咨询此事。我们确实有一个包含此容器的卷。 - Doug Fir
1
我对这个错误信息的看法和你一样,如果你要给出错误标签,至少让错误模糊一些。特别是那些明确指出“没有这样的文件或目录”的错误信息只会让人走弯路。 - r2evans

0

我不是Docker的专家,也找不到特定的文档。但从经验来看,每次添加新层(例如使用RUN)时,来自先前层的任何复制都会被“遗忘”(注意:如果有人发现我错了,请纠正我并指明文档)。

因此,我建议您尝试合并RUN参数,并在需要RUN语句之前添加每个文件。这样做还可以减小最终镜像的大小,因为层的创建和保留方式。

FROM rocker/tidyverse:3.6.3
ENV ADD=SHINY
ENV ROOT=TRUE
ENV PASSWORD='abc123'
#add files (could also combine them into a single tar file and add it. Or add it via git, which is often used)
ADD odbc.ini /etc/odbc.ini
ADD install_packages.R /tmp/install_packages.R
ADD flagship_ecommerce /home/rstudio/blah/zprojects/flagship_ecommerce
ADD commission_junction /home/rstudio/blah/zprojects/commission_junction
#Combine all runs into a single statement
RUN apt-get update && apt-get install -y \
   less \
   vim  \
   unixodbc unixodbc-dev \
   odbc-postgresql \
 && Rscript /tmp/install_packages.R \
 && rm -R /tmp/* \
 && mkdir /srv/shiny-server \
 && ln -s /home/rstudio/blah/zprojects/ /srv/shiny-server/

请注意,现在add技术上是在使用它的语句之前出现的。

嗨,谢谢你的建议。我刚试了一下,但结果还是一样,出现了上面关于没有这个文件或目录的错误信息。还是非常感谢你。 - Doug Fir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接