Problems installing msodbcsql17 with Docker - docker

I have a dockerfile to upload some python code on Azure. It has been working for a few months, but today it suddenly stopped working.
The relevant commands in the Dockerfile are:
FROM python:3.9.5
:
:
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN exit
RUN apt-get update && ACCEPT_EULA=Y apt-get install msodbcsql17
The error message is that appeared today is:
Err:1 https://packages.microsoft.com/ubuntu/20.04/prod focal/main amd64 msodbcsql17 amd64 17.7.2.1-1
404 Not Found [IP: 104.214.230.139 443]
E: Failed to fetch https://packages.microsoft.com/ubuntu/20.04/prod/pool/main/m/msodbcsql17/msodbcsql17_17.7.2.1-1_amd64.deb 404 Not Found [IP: 104.214.230.139 443]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
The command '/bin/sh -c apt-get update && ACCEPT_EULA=Y apt-get install msodbcsql17' returned a non-zero code: 100
2021/06/16 20:50:56 Container failed during run: build. No retries remaining.
failed to run step ID: build: exit status 100
I believe this might be related to the .deb files being moved - or that some computer at Microsoft is down?
A good workaround would maybe be to download the relevant msodbcsql17 package directly, but I was unable to find this package in the normal repos?

There seems to be some ongoing trouble with microsoft repos for some linux distributions (including ubuntu and debian). Not clear when this will be fixed.
https://github.com/dotnet/core/issues/6381
https://github.com/MicrosoftDocs/sql-docs/issues/6494

The answer might be related to this post:
https://github.com/dotnet/core/issues/6381
It seems that some Ubuntu repositories are broken.
Hopefully it will be fixed soon...

I Will keep an eye on the resolve, but I have the same issue using:
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17
# optional: for bcp and sqlcmd
RUN ACCEPT_EULA=Y apt-get install -y mssql-tools
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
# optional: for unixODBC development headers
RUN apt-get install -y unixodbc-dev

Related

dockerfile does not build due to failed size validation

My dockerfile used to build successfully.
I tried to build today (5 days after successful build) with docker build -t fv ., and kept getting the following error:
failed commit on ref "layer-sha256:7a3de07a56633b9096304d02c47f097f3e28ae6c6dd442d1e7c4d26452ecd90a": "layer-sha256:7a3de07a56633b9096304d02c47f097f3e28ae6c6dd442d1e7c4d26452ecd90a" failed size validation: 581433721 != 600361569: failed precondition
any suggestions what this means and how to correct?
my dockerfile is:
FROM rocker/verse
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends build-essential libpq-dev python3.8 python3-pip python3-setuptools python3-dev
RUN pip3 install --upgrade pip
ADD . ./home/rstudio
ADD requirements.txt .
ADD install_packages.r .
# Miniconda and dependencies
RUN cd /tmp/ && \
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3 && \
/root/miniconda3/condabin/conda install -y python=3.7
ENV PATH=$PATH:/root/miniconda3/bin
#RUN npm install phantomjs-prebuilt --phantomjs_cdnurl=http://cnpmjs.org/downloads
# installing python libraries
RUN pip3 install -r requirements.txt
# installing r libraries
RUN Rscript install_packages.r
another reference I got was:
=> => sha256:7a3de07a56633b9096304d02c47f097f3e28ae6c6dd442d1e7c4d26452ecd90a 580.97MB / 600.36MB 1150.8s
------
> [ 1/10] FROM docker.io/rocker/verse#sha256:3b417b991a32cc8bf9c1fa173ec976a5cc65522a76918df61b5c6cf6261e63a5:
Would this be because of an issue with the base image pulled?
I found that docker build would fail with this error, but it would work if I first pulled the failing image with docker pull <image> and then ran docker build.
this was due to security encryption from my local ip.
when tethering, was able to generate the docker image with non problems
On my side, I got something like below
------
> [1/3] FROM docker.io/library/python#sha256:10fc14aa6ae69f69e4c953cffd9b0964843d8c163950491d2138af891377bc1d:
------
failed commit on ref "layer-sha256:049db2c7eb8a5bd3833cac2f58c6c72b481f1a0288a8b20527529c4970b52762": "layer-sha256:049db2c7eb8a5bd3833cac2f58c6c72b481f1a0288a8b20527529c4970b52762" failed size validation: 311296 != 3056504: failed precondition
On my side, I managed to solve this by disconnecting from a VPN I was connected to.

laravel-with-docker-example project fails to build

I am trying to run below project with docker.
https://github.com/kyleferguson/laravel-with-docker-example
which has the below docker file.
FROM php:7-fpm
RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client \
&& docker-php-ext-install mcrypt pdo_mysql
WORKDIR /var/www
When i run the "docker-compose up" after running the "composer install".
I get below errors.
executor failed running [/bin/sh -c apt-get update && apt-get install
-y libmcrypt-dev mariadb-client && docker-php-ext-install mcrypt pdo_mysql]: exit code: 1 ERROR: Service 'app' failed to build
Any idea on how to fix this?
Note:
I already tried replacing mariadb-client with mysql-client and default-my-client, still the same issue.
You have a couple problems here, which is why switching to mariadb didn't work on its own.
One way to make it more clear what the problem is, is to bash into a container created from your base image and run the commands manually.
docker run -it php:7-fpm bash
From there if you run each install individually you'll see where you are failing:
# apt-get install -y mysql-client
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package mysql-client
Either add a repo that provides mysql, or use mariadb.
# docker-php-ext-install mcrypt
error: /usr/src/php/ext/mcrypt does not exist
mcrypt was removed in php 7.2 so you'll need to use pecl to install it, if you really need it.
Unless you're running a very old version of Laravel, you shouldn't need mcrypt.

Why am I getting Unable to correct problems, you have held broken packages

Trying to run Dockerfile and it fails at installing npm.
ERROR:
Unable to correct problems, you have held broken packages.
The command '/bin/sh -c apt-get install -y npm' returned a non-zero code: 100
Dockerfile:
FROM ubuntu:14.04
MAINTAINER Giacomo Vacca "giacomo.vacca#gmail.com"
ENV REFRESHED_AT 2015-01-19
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get autoremove
RUN npm -v
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install --yes curl
RUN curl --silent --location http://deb.nodesource.com/setup_0.10 | sudo bash -
RUN apt-get install -y nodejs
RUN apt-get install --yes build-essential
RUN rm /usr/bin/node
# needs this to find the nodejs exec
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN apt-get install -y npm <--- FAIL
RUN /usr/bin/npm install socket.io#0.9.14
EXPOSE 8080
ENTRYPOINT ["/usr/bin/node", "/root/server.js"]
You don't need to install npm from the ubuntu distribution with:
RUN apt-get install -y npm
because it's already installed by the nodejs package from nodesource. You can check it with:
dpkg -L nodejs | grep "/usr/bin/npm"

Connect docker python to SQL server with pyodbc

I'm trying to connect a pyodbc python script running in a docker container to login to a MSSQL database I have tried all sorts of docker files, but not been able to make the connection (fails when bulding the docker or when python tries to connect), Does anyone have a working dockerfile, using pyodbc:
Dockerfile:
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Run app.py when the container launches
CMD ["python", "App.py"]
requirements.TXT
pyodbc
App.Py
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=xxxx;'
'Database=xxx;'
'UID=xxxx;'
'PWD=xxxx')
cursor = connection.cursor()
cursor.execute("SELECT [Id],[Name] FROM [DCMM].[config].[Models]")
for row in cursor.fetchall():
print(row.Name)
connection.close()
Bulding the container
docker build -t sqltest .
Output:
Sending build context to Docker daemon 4.096kB
Step 1/5 : FROM python:2.7-slim
---> 426d65ab9a72
Step 2/5 : WORKDIR /app
---> Using cache
---> 725f35122880
Step 3/5 : ADD . /app
---> 3feb8b7744f7
Removing intermediate container 4214091a111a
Step 4/5 : RUN pip install -r requirements.txt
---> Running in 27aa4dcfe738
Collecting pyodbc (from -r requirements.txt (line 1))
Downloading pyodbc-4.0.17.tar.gz (196kB)
Building wheels for collected packages: pyodbc
Running setup.py bdist_wheel for pyodbc: started
Running setup.py bdist_wheel for pyodbc: finished with status 'error'
Failed building wheel for pyodbc
Complete output from command /usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-EfWsmy/pyodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpa3S13tpip-wheel- --python-tag cp27:
running bdist_wheel
running build
running build_ext
building 'pyodbc' extension
creating build
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/src
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -DPYODBC_VERSION=4.0.17 -DSQL_WCHART_CONVERT=1 -I/usr/local/include/python2.7 -c src/cursor.cpp -o build/temp.linux-x86_64-2.7/src/cursor.o -Wno-write-strings
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
----------------------------------------
Running setup.py clean for pyodbc
Failed to build pyodbc
Installing collected packages: pyodbc
Running setup.py install for pyodbc: started
Running setup.py install for pyodbc: finished with status 'error'
Complete output from command /usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-EfWsmy/pyodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-BV4sRM-record/install-record.txt --single-version-externally-managed --compile:
running install
running build
running build_ext
building 'pyodbc' extension
creating build
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/src
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -DPYODBC_VERSION=4.0.17 -DSQL_WCHART_CONVERT=1 -I/usr/local/include/python2.7 -c src/cursor.cpp -o build/temp.linux-x86_64-2.7/src/cursor.o -Wno-write-strings
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
----------------------------------------
Command "/usr/local/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-EfWsmy/pyodbc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-BV4sRM-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-EfWsmy/pyodbc/
The command '/bin/sh -c pip install -r requirements.txt' returned a non-zero code: 1
Need to Run:
sudo apt-get install gcc
need to add a odbcinst.ini file containing:
[FreeTDS]Description=FreeTDS Driver Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so Setup=/usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
need to add folowing to docker file
ADD odbcinst.ini /etc/odbcinst.ini
RUN apt-get update
RUN apt-get install -y tdsodbc unixodbc-dev
RUN apt install unixodbc-bin -y
RUN apt-get clean -y
need to change connection in .py to
connection = pyodbc.connect('Driver={FreeTDS};'
'Server=xxxxx;'
'Database=DCMM;'
'UID=xxxxx;'
'PWD=xxxxx')
Now the container compiles, and gets data from SQL server
Running through this recently I found it was necessary to additionally include the following line (note that it did not build without this step):
RUN apt-get install --reinstall build-essential -y
The full Dockerfile looks as follows:
# parent image
FROM python:3.7-slim
# install FreeTDS and dependencies
RUN apt-get update \
&& apt-get install unixodbc -y \
&& apt-get install unixodbc-dev -y \
&& apt-get install freetds-dev -y \
&& apt-get install freetds-bin -y \
&& apt-get install tdsodbc -y \
&& apt-get install --reinstall build-essential -y
# populate "ocbcinst.ini"
RUN echo "[FreeTDS]\n\
Description = FreeTDS unixODBC Driver\n\
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\n\
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so" >> /etc/odbcinst.ini
# install pyodbc (and, optionally, sqlalchemy)
RUN pip install --trusted-host pypi.python.org pyodbc==4.0.26 sqlalchemy==1.3.5
# run app.py upon container launch
CMD ["python", "app.py"]
Here's one way to then actually establish the connection inside app.py, via sqlalchemy (and assuming port 1433):
import sqlalchemy as sa
args = (username, password, server, database)
connstr = "mssql+pyodbc://{}:{}#{}/{}?driver=FreeTDS&port=1433&odbc_options='TDS_Version=8.0'"
engine = sa.create_engine(connstr.format(*args))
Based on Kåre Rasmussen's answer, here's a complete dockerfile for further use.
Make sure to edit the last two lines according to your architecture! They should reflect the actual paths to libtdsodbc.so and libtdsS.so.
If you're not sure about the paths to libtdsodbc.so and libtdsS.so, try dpkg --search libtdsodbc.so and dpkg --search libtdsS.so.
FROM python:3
#Install FreeTDS and dependencies for PyODBC
RUN apt-get update && apt-get install -y tdsodbc unixodbc-dev \
&& apt install unixodbc-bin -y \
&& apt-get clean -y
RUN echo "[FreeTDS]\n\
Description = FreeTDS unixODBC Driver\n\
Driver = /usr/lib/arm-linux-gnueabi/odbc/libtdsodbc.so\n\
Setup = /usr/lib/arm-linux-gnueabi/odbc/libtdsS.so" >> /etc/odbcinst.ini
Afterwards, install PyODBC, COPY your app and run it.
I was unable to use all of the above resolutions, I was keeping al kind of errors relating to the pyodbc package, in particular:
ImportError: libodbc.so.2: cannot open shared object file: No such file or directory.
I ended up with another resolution which defines the ODBC SQL Server Driver specifically for an Ubuntu 18.04 Docker image, in this case ODBC Driver 17 for SQL Server. In my specific use case I needed to make the connection to my MySQL database server on Azure via Flask SQLAlchemy, but the latter is not a necessity for the Docker configuration.
Dockerfile, with most important part adding the Microsoft repository and installing msodbcsql17 and unixodbc-dev:
# Ubuntu 18.04 base with Python runtime and pyodbc to connect to SQL Server
FROM ubuntu:18.04
WORKDIR /app
# apt-get and system utilities
RUN apt-get update && apt-get install -y \
curl apt-utils apt-transport-https debconf-utils gcc build-essential g++-5\
&& rm -rf /var/lib/apt/lists/*
# adding custom Microsoft repository
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
# install SQL Server drivers
RUN apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql17 unixodbc-dev
# install SQL Server tools
RUN apt-get update && ACCEPT_EULA=Y apt-get install -y mssql-tools
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
RUN /bin/bash -c "source ~/.bashrc"
# python libraries
RUN apt-get update -y && \
apt-get install -y python3-pip python3-dev
# install necessary locales, this prevents any locale errors related to Microsoft packages
RUN apt-get update && apt-get install -y locales \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen
# copy requirements and install packages, I added this for general use
COPY ./requirements.txt > ./requirements.txt
RUN pip3 install -r ./requirements.txt
# you can also use regular install of the packages
RUN pip3 install pyodbc SQLAlchemy
# and if you are also planning to use Flask and Flask-SQLAlchemy
Run pip3 install Flask Flask-SQLAlchemy
COPY ..
# run your app via entrypoint or change the CMD command to your regular command
COPY docker-entrypoint.sh wsgi.py ./
CMD ["./docker-entrypoint.sh"]
This should build without any errors in Docker.
My database url looked like this:
import urllib.parse
# name the sepcific ODBC driver by version number, we installed msodbcsql17
params = urllib.parse.quote_plus("DRIVER={ODBC Driver 17 for SQL Server};SERVER=<your.database.windows.net>;DATABASE=<your-db-name>;UID=<username>;PWD=<password>")
db_uri = "mssql+pyodbc:///?odbc_connect={PARAMS}".format(PARAMS=params)
And for the bonus if you are using Flask-SQLAlchemy, your app config should contain something like this:
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SQLALCHEMY_DATABASE_URI"] = db_uri # from above
Happy coding!
How to install the necessary dependencies for pyodbc is related to the linux distribution and its version (in docker case, that is the base image of your docker image). If none of the above work for you, you can figure out the commands by trying in the docker container instance.
First, exec into the docker container
docker exec -it <container id> bash
Try various ways to get the distribution name and version of your linux. Then try different instructions in Install the Microsoft ODBC driver for SQL Server (Linux)
Here is a working example for Debian 9 based images, deriving exactly as the document instructions.
# Install pyodbc dependencies
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get -y install msodbcsql17
RUN apt-get -y install unixodbc-dev
RUN pip install pyodbc
For me to solve this issue I also had to add the following 2 lines in the dockerfile:
RUN echo MinProtocol = TLSv1.0 >> /etc/ssl/openssl.cnf
RUN echo CipherString = DEFAULT#SECLEVEL=1 >> /etc/ssl/openssl.cnf
For those who wanted to do official microsoft approach to install odbc driver and use python:slim docker image, you can use this as DockerFile:
FROM python:3.9-slim
RUN apt-get -y update && apt-get install -y curl gnupg
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
# download appropriate package for the OS version
# Debian 11
RUN curl https://packages.microsoft.com/config/debian/11/prod.list \
> /etc/apt/sources.list.d/mssql-release.list
RUN exit
RUN apt-get -y update
RUN ACCEPT_EULA=Y apt-get install -y msodbcsql18
Then for sqlalchemy's this can be called:
con_str = f"mssql+pyodbc://{username}:{password}#{host}/{db}?" \
"driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes"
engine = create_engine(con_str)
I created a Gist on GitHub on how to do this. I hope it helps. I had to piece things together from what I found on different resources.
https://gist.github.com/joshatxantie/4bcf5d0243fba63845fce7cc40365a3a
Goodluck!
I fixed this problem by using pypyodbc instead of pyodbc.
pip install pypyodbc==1.3.5
https://pypi.org/project/pypyodbc/
Found the hint here:
https://github.com/Azure/azure-functions-python-worker/issues/249
For not more problem use library for python
pymssql this not need install driver
pip install pymssql
import pymssql
conn = pymssql.connect(server, user, password, "tempdb")
cursor = conn.cursor(as_dict=True)
cursor.execute('SELECT * FROM persons WHERE salesrep=%s', 'John Doe')
for row in cursor:
print("ID=%d, Name=%s" % (row['id'], row['name']))
conn.close()
and work in docker

Docker Debian install fails

I have a Dockerfile that works, but if I add any new dependencies to the apt-get install command, it fails. For example, this works:
FROM debian:stable
RUN apt-get update
RUN apt-get install -y \
python \
...
apache2
But if I try this, it fails:
FROM debian:stable
RUN apt-get update
RUN apt-get install -y \
python \
...
apache2
python-mysqldb
I can replace python-mysqldb with anything else, git-core, for example, and it will still fail with the same error message:
Unable to correct missing packages.
E: Failed to fetch http://security.debian.org/pool/updates/main/l/linux/linux-libc-dev_3.16.7-ckt11-1+deb8u5_amd64.deb 404 Not Found [IP: 149.20.20.6 80]
E: Aborting install.
Any thoughts on why adding a new dependency causes the failure and how to fix it?
I've found that you need to join the update & install command into the same RUN block.
eg:
RUN apt-get update \
&& apt-get install -y \
python \
...
apache2 \
python-mysqldb
According to this post describing the issue
By default, Docker cache your commands to reduce time spent building
images. Unless there was any change before such commands (or at the
same line).
Meanwhile, I notice that the AWS examples separate them, as you have them. So I dunno if it works different there. Maybe they disable the cache by default.

Resources