Docker中R包odbc二进制转源码安装报错sql.h缺失解决问询
问题描述
我搭建了一个Docker应用,通过RUN Rscript requirements.R执行install.packages('odbc')安装R包。此前正常运行的应用近期报错:
Error in library(odbc) : there is no package called ‘odbc’
查看构建日志发现:
- 安装成功时显示
installing *binary* package ‘odbc’ - 失败时显示
installing *source* package ‘odbc’,同时触发fatal error: sql.h: No such file or directory错误
我已尝试添加RUN sudo apt-get install unixodbc unixodbc-dev和RUN sudo apt install unixodbc-dev,但问题未解决。另外在Azure流水线中运行时,显示installing *binary* package ‘odbc’且编译成功。
以下是我的Dockerfile内容:
FROM rocker/verse ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends build-essential libpq-dev python3.9 python3-pip python3-setuptools python3-dev RUN pip3 install --upgrade pip RUN apt -y install libpng-dev WORKDIR /app RUN apt-get install --yes xvfb libgconf-2-4 RUN wget https://github.com/plotly/orca/releases/download/v1.1.1/orca-1.1.1-x86_64.AppImage -P /home RUN chmod 777 /home/orca-1.1.1-x86_64.AppImage ENV PATH="${PATH}:/home/orca-1.1.1-x86_64.AppImage" RUN cd /home && /home/orca-1.1.1-x86_64.AppImage --appimage-extract RUN printf '#!/bin/bash \nxvfb-run --auto-servernum --server-args "-screen 0 640x480x24" /home/squashfs-root/app/orca "$@"' > /usr/bin/orca RUN chmod 777 /usr/bin/orca RUN chmod -R 777 /home/squashfs-root/ RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && mkdir -p /opt/chromedriver-$CHROMEDRIVER_VERSION && curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip && unzip -qq /tmp/chromedriver_linux64.zip -d /opt/chromedriver-$CHROMEDRIVER_VERSION && rm /tmp/chromedriver_linux64.zip && chmod +x /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver && ln -fs /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver /usr/local/bin/chromedriver RUN apt-get update && apt-get install -y gnupg2 RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list RUN apt-get update && apt-get -y install google-chrome-stable RUN wget https://downloads.vivaldi.com/stable/vivaldi-stable_5.5.2805.35-1_amd64.deb RUN apt-get update && apt-get install -y ./vivaldi-stable_5.5.2805.35-1_amd64.deb && rm -rf /var/lib/apt/lists/* # Install odbc RUN sudo su RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - RUN curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list > /etc/apt/sources.list.d/mssql-release.list RUN exit RUN sudo apt-get clean RUN sudo apt-get update && apt install -y apt-utils RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections RUN sudo apt-get remove -y libodbc2 libodbcinst2 odbcinst unixodbc-common RUN sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17 # set up app COPY . /app RUN pip3 install -r requirements.txt RUN Rscript requirements.R ## Start and enable SSH COPY sshd_config /etc/ssh/ RUN apt-get update \ && apt-get install -y --no-install-recommends dialog \ && apt-get install -y --no-install-recommends openssh-server \ && echo "root:Docker!" | chpasswd \ && chmod u+x /app/entrypoint.sh EXPOSE 8501 2222 RUN chmod -R 777 /app WORKDIR /app RUN ls . RUN service ssh start CMD ["/bin/bash", "-c", "service ssh start; streamlit run app.py"]
问题分析
核心问题是R安装odbc包时无法获取预编译二进制包,只能从源码编译,但缺少必要的编译依赖。Azure环境成功是因为对应的镜像源提供了预编译的二进制odbc包,而本地/其他环境的镜像源没有,触发了源码编译流程。
之前尝试安装unixodbc-dev未生效,原因可能是:
- 依赖安装顺序错误:移除旧ODBC组件后才安装编译依赖,导致依赖缺失
- Docker命令上下文问题:每个
RUN都是独立进程,RUN sudo su不会让后续RUN以root身份执行,后续sudo执行的依赖安装时机不对
解决方案
1. 调整依赖安装顺序,确保编译依赖提前到位
修改Dockerfile中ODBC相关安装部分,移除不必要的用户切换,提前安装编译所需依赖:
# 提前安装编译odbc必需的依赖 RUN apt-get update && apt-get install -y --no-install-recommends unixodbc unixodbc-dev # 配置微软ODBC源并安装驱动 RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - RUN curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list > /etc/apt/sources.list.d/mssql-release.list RUN apt-get clean && apt-get update RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17
rocker/verse镜像默认以root身份运行,无需sudo su和exit命令- 先安装
unixodbc-dev,确保源码编译时能找到sql.h头文件
2. 强制优先使用二进制包安装(可选)
修改requirements.R中的安装命令,强制指定使用二进制包:
install.packages('odbc', type="binary")
该方法依赖镜像源是否提供对应版本的二进制包,Azure环境就是自动使用二进制包才成功。
3. 合并APT命令优化镜像构建
将相关APT命令合并,减少镜像层并避免缓存问题:
RUN apt-get update && apt-get install -y --no-install-recommends \ unixodbc \ unixodbc-dev \ apt-utils \ && rm -rf /var/lib/apt/lists/*
内容的提问来源于stack exchange,提问作者frank
相关产品推荐
相关产品推荐

