djangolinuxdockerfreetdsdjango-pyodbc-azure

[FreeTDS][SQL Server]Login failed for user


I am developing on a windows and trying to run the Django application in Linux container with Gunicorn and Nginx to deploy it to Linux machine in production.

I mostly used this Connect docker python to SQL server with pyodbc post as a guide but I think I have tried every solution found online about this error.

If I ping DB server from container it gets connected so the port 1433 is open and everything should be good to go. But for some reason I'm getting error django.db.utils.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Login failed for user

Django settings.py

DATABASES = {
    'default': {
        'ENGINE': "sql_server.pyodbc",
        'NAME': 'database1',
        'HOST': '123.45.6.78',
        'PORT':'1433',
        'USER': "user",
        'PASSWORD': "pswd",
        'OPTIONS': {
            "driver": "FreeTDS",
            "host_is_server": True,
            "unicode_results": True,
            "extra_params": "tds_version=7.3",
        }
    }
}

Dockerfile

# start from an official image
FROM python:3

# arbitrary location choice: you can change the directory
RUN mkdir -p /opt/services/djangoapp/src
WORKDIR /opt/services/djangoapp/src

#Install FreeTDS and dependencies for PyODBC
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\
TDS_Version = '7.3'\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

# modify "freetds.conf"
RUN echo "[mssql]\n\
host = 172.30.2.18\n\
port = 1433\n\
tds version = 7.3" >> /etc/freetds/freetds.conf

RUN echo MinProtocol = TLSv1.0 >> /etc/ssl/openssl.cnf
RUN echo CipherString = DEFAULT@SECLEVEL=1 >> /etc/ssl/openssl.cnf


# install our dependencies
# we use --system flag because we don't need an extra virtualenv
COPY Pipfile Pipfile.lock /opt/services/djangoapp/src/
RUN pip install pipenv && pipenv install --system

# copy our project code
COPY . /opt/services/djangoapp/src

# expose the port 8000
EXPOSE 8000

# define the default command to run when starting the container
CMD ["gunicorn", "--chdir", "app", "--bind", ":8000", "config.wsgi:application"]

docker-compose.yml

version: '3'

services:

  djangoapp:
    build: .
    volumes:
      - .:/opt/services/djangoapp/src
      - /static:/static
    networks:  # <-- here
      - nginx_network

  nginx:
    image: nginx:1.13
    ports:
      - 8000:80
    volumes:
      - ./config/nginx/conf.d:/etc/nginx/conf.d
      - /static:/static
    depends_on:
      - djangoapp
    networks:  # <-- here
      - nginx_network

networks:  # <-- and here
  nginx_network:
    driver: bridge

Pipfile

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
django = "==2.1.0"
pyodbc = "==4.0.28"
django-pyodbc-azure = "*"
django-datatables-view = "*"            
gunicorn = "*"
whitenoise = "*"


[requires]
python_version = "3.8"

Solution

  • I finally solved it myself. Had to add port 1433 to nginx in .yml file.

    Like this

      nginx:
        image: nginx:1.13
        ports:
          - 8000:80
          - 1433:1433
        volumes:
          - ./config/nginx/conf.d:/etc/nginx/conf.d
          - /static:/static
        depends_on:
          - djangoapp
        networks:  # <-- here
          - nginx_network