mssql-django를 사용한 컨테이너 및 로컬 개발

이 가이드는 Windows, Linux, macOS, Docker 컨테이너, devcontainer 및 CI 파이프라인 전반에서 mssql-django 백엔드로 작업하는 Django 개발자를 위한 환경 설정을 다룹니다.

사전 요구 사항

  • Python 3.10부터 3.14까지. Django 6.0과 6.1은 Python 3.12 및 이후 버전이 필요합니다.
  • Docker Desktop(컨테이너 기반 개발용)
  • 기본 pyodbc 경로를 사용할 때 Microsoft ODBC 드라이버 17 또는 18을 SQL Server에 사용할 수 있습니다. SQL Server ODBC 드라이버 다운로드를 참조하세요.
  • 필요한 mssql-python 패키지와 호환되는 기본 이미지: Windows x64, Python 3.11 이후 버전이 포함된 Windows ARM64, macOS 15 이후 버전, 또는 glibc 2.28 이후 버전이 적용된 Linux x64/ARM64, 또는 musl 1.2 이후 버전이 포함됩니다. ARM64용 SUSE Linux는 지원되지 않습니다.

mssql-python 경로는 별도의 Microsoft ODBC 드라이버 for SQL Server 설치가 필요하지 않습니다. 여전히 unixODBC 런타임이 필요합니다. 왜냐하면 Django가 pyodbc를 로드할 때 백엔드가 pyodbc를 가져오기 때문입니다. 자세한 내용은 mssql-django의 데이터베이스 드라이버 선택을 참조하세요.

sqlcmd(Go) 유틸리티는 단일 명령으로 SQL Server 컨테이너를 만들 수 있습니다. Docker 이미지 끌어오기, 암호 생성, 포트 할당 및 연결 컨텍스트를 자동으로 처리합니다.

sqlcmd create mssql --accept-eula

샘플 데이터베이스가 이미 연결된 컨테이너를 만들려면 다음을 수행합니다.

sqlcmd create mssql --accept-eula --using https://aka.ms/AdventureWorksLT.bak

만든 sqlcmd 후 즉시 쿼리할 수 있도록 연결 컨텍스트를 저장합니다.

sqlcmd query "SELECT @@VERSION"

만들 때 인쇄된 연결 세부 정보를 sqlcmd 사용하여 연결하도록 Django를 구성합니다. 나중에 다시 가져오려면 sqlcmd config view을 사용하세요.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "master",
        "USER": "sa",
        "PASSWORD": "<password from sqlcmd output>",
        "HOST": "localhost",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "TrustServerCertificate=yes",
        },
    },
}

완료되면 컨테이너를 중지하거나 삭제합니다.

sqlcmd stop
sqlcmd delete

Tip

실행 sqlcmd create mssql --user-database mydb 하여 개발 준비가 된 빈 사용자 데이터베이스가 있는 컨테이너를 만듭니다.

Visual Studio Code의 로컬 SQL Server

Visual Studio Code MSSQL 확장은 편집기에서 직접 로컬 SQL Server 컨테이너를 만들 수 있습니다.

  1. 작업 표시줄에서 SQL Server 보기를 엽니다.
  2. 연결>추가 로컬 SQL Server 만들기를 선택합니다(또는 명령 팔레트 사용: MS SQL: 로컬 SQL Server 만들기).
  3. SQL Server 버전을 선택하고 EULA에 동의합니다.
  4. 확장은 컨테이너 이미지를 끌어오고, 암호를 생성하고, 연결 프로필을 자동으로 추가합니다.

컨테이너가 실행되면 Django 코드로 전환하기 전에 데이터베이스를 찾아보고, 쿼리를 실행하고, Visual Studio Code 개체를 관리할 수 있습니다.

Docker를 사용하여 로컬 SQL Server

컨테이너를 직접 관리하려는 경우 공식 SQL Server 컨테이너 이미지는 다음 두 가지 환경 변수와 함께 작동합니다.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<strong_password>" \
  -p 1433:1433 --name sql1 \
  -d mcr.microsoft.com/mssql/server:2022-latest

Important

SQL Server 컨테이너에는 MSSQL_SA_PASSWORD를 사용합니다. 이전 SA_PASSWORD 변수는 더 이상 사용되지 않습니다. 암호는 대문자, 소문자, 숫자 및 특수 문자가 있는 8자 이상의 SQL Server 복잡성 요구 사항을 충족해야 합니다.

컨테이너가 시작될 때까지 몇 초 정도 기다린 다음 마이그레이션을 실행합니다.

python manage.py migrate
python manage.py createsuperuser

Django 애플리케이션용 Dockerfile

기본 pyodbc 경로를 통해 SQL Server에 연결하는 Django 애플리케이션용 최소 Docker파일을 만드세요. ODBC 드라이버는 Python 기본 이미지와 함께 제공되지 않는 주요 종속성입니다.

FROM python:3.12-slim

# Install ODBC Driver 18 for SQL Server
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl gnupg2 && \
    curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
        gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg && \
    echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > \
        /etc/apt/sources.list.d/mssql-release.list && \
    apt-get update && \
    ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 unixodbc-dev && \
    apt-get purge -y curl gnupg2 && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# Collect static files
RUN python manage.py collectstatic --noinput

EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]

Important

정화 후에는 추가 apt-get autoremove -y 하지 마세요. 이는 ODBC 드라이버가 런타임에 로드하지만 종속성으로 선언하지는 않는 libgssapi-krb5-2를 제거합니다. 빌드는 여전히 성공하지만, 모든 연결이 실패합니다. pyodbc 오류는 오해의 소지가 있습니다: 버전 18이 로드되지 않고, mssql-django는 버전 17로 되돌아가며, 오류가 실패한 버전 18이 아니라 누락된 버전 17을 명명합니다.

귀하의 requirements.txt:

django>=5.2,<6.2
mssql-django>=2.0
gunicorn>=22.0

데이터베이스 별칭이 mssql-python 드라이버 경로를 "python_driver": "mssql_python"사용한다면, 여전히 unixODBC가 필요합니다. 왜냐하면 백엔드가 Django를 로드할 때 pyodbc가 가져오기 때문입니다. Microsoft 패키지 저장소나 msodbcsql18, 가 필요하지 않으므로 ODBC 설치 블록은 다음과 같이 축소됩니다:

RUN apt-get update && \
    apt-get install -y --no-install-recommends unixodbc libkrb5-3 libgssapi-krb5-2 && \
    rm -rf /var/lib/apt/lists/*

빌드 및 실행:

docker build -t mydjango .
docker run -e "DB_HOST=host.docker.internal" -e "DB_NAME=<database>" \
  -e "DB_USER=<user_id>" -e "DB_PASSWORD=<password>" \
  -p 8000:8000 mydjango

메모

Docker Desktop(Windows 및 macOS)에서 호스트 머신의 SQL Server에 연결하려면 host.docker.internal을 사용합니다. Linux에서 대신 사용합니다 --network host .

Devcontainer 설정

SQL Server를 사이드카 서비스로 포함하는 Visual Studio Code용 .devcontainer/devcontainer.json를 만듭니다.

{
    "name": "Django + SQL Server",
    "image": "mcr.microsoft.com/devcontainers/python:3",
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
    "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
    "postCreateCommand": "bash .devcontainer/post-create.sh",
    "forwardPorts": [1433, 8000],
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

이 개발 컨테이너는 기본 pyodbc 경로와 Python 의존성에 대한 ODBC 드라이버를 설치하지만 SQL Server 인스턴스는 포함하지 않습니다. Docker-in-Docker를 사용할 수 있으므로 sqlcmd create mssql --accept-eula를 사용해 devcontainer 내부에서 SQL Server 인스턴스를 시작하거나, 기본 제공 SQL Server 서비스를 사용하려면 Docker Compose 방식을 사용하세요. mssql-python 경로를 사용하는 경우 post-create 스크립트에서 msodbcsql18 install을 sudo apt-get install -y unixodbc libkrb5-3 libgssapi-krb5-2로 바꾸세요.

pyodbc 및 Python 종속성용 ODBC 드라이버를 설치하려면 .devcontainer/post-create.sh을 생성하세요:

#!/bin/bash
set -e

# Install ODBC Driver 18
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
    sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" | \
    sudo tee /etc/apt/sources.list.d/mssql-release.list
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev

pip install -r requirements.txt

Docker Compose를 사용하여 SQL Server 포함

devcontainer에 서비스로 SQL Server 포함하려면 Docker Compose를 사용합니다.

.devcontainer/docker-compose.yml:

services:
  app:
    image: mcr.microsoft.com/devcontainers/python:3
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    depends_on:
      - db

  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      MSSQL_SA_PASSWORD: "<strong_password>"
    ports:
      - "1433:1433"

.devcontainer/devcontainer.json (Compose 버전):

{
    "name": "Django + SQL Server",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/workspace",
    "postCreateCommand": "bash .devcontainer/post-create.sh",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

이름으로 django를 SQL Server 서비스에 연결합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "mydb",
        "USER": "sa",
        "PASSWORD": "<password>",
        "HOST": "db",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "TrustServerCertificate=yes",
        },
    },
}

개발을 위한 인증

애플리케이션이 실행되는 위치와 데이터베이스가 호스트되는 위치에 따라 인증 방법을 선택합니다.

Azure SQL 대한 로컬 개발

Azure SQL을 대상으로 로컬 개발을 할 때는 pyodbc 경로에서 TOKEN의 Authentication=ActiveDirectoryDefault를 사용하거나, OPTIONS["extra_params"]와 함께 DefaultAzureCredential 설정을 사용합니다. DefaultAzureCredential이(가) az login 세션을 자동으로 인식합니다:

from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "mydb",
        "HOST": "<server>.database.windows.net",
        "PORT": "1433",
        "TOKEN": token,
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

전체 인증 매트릭스 및 주의 사항에 대해서는 mssql-django를 사용한 Microsoft Entra 인증을 참조하세요.

Azure SQL 대한 컨테이너 개발

Azure에서 실행 중인 컨테이너의 경우 TOKEN 설정을 ManagedIdentityCredential와 함께 사용하여 Microsoft Entra 액세스 토큰을 명시적으로 획득합니다.

from azure.identity import ManagedIdentityCredential

credential = ManagedIdentityCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
  "default": {
    "ENGINE": "mssql",
    "NAME": "mydb",
    "HOST": "<server>.database.windows.net",
    "PORT": "1433",
    "TOKEN": token,
    "OPTIONS": {
      "driver": "ODBC Driver 18 for SQL Server",
    },
  },
}

인증 방법의 전체 목록은 mssql-django를 사용한 Microsoft Entra 인증을 참조하세요.

CI 파이프라인 설정

CI 파이프라인의 SQL Server 서비스 컨테이너에 대해 Django 테스트 제품군을 실행합니다.

GitHub Actions (GitHub 액션)

name: Django Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      sqlserver:
        image: mcr.microsoft.com/mssql/server:2022-latest
        env:
          ACCEPT_EULA: Y
          MSSQL_SA_PASSWORD: "<strong_password>"
        ports:
          - 1433:1433
        options: >-
          --health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P \"$$MSSQL_SA_PASSWORD\" -C -Q 'SELECT 1'"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install ODBC Driver for pyodbc
        run: |
          curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
              sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
          echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod $(lsb_release -cs) main" | \
              sudo tee /etc/apt/sources.list.d/mssql-release.list
          sudo apt-get update
          sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        env:
          DB_HOST: localhost
          DB_NAME: "master"
          DB_USER: "<user_id>"
          DB_PASSWORD: "<password>"
        run: python manage.py test

Tip

공유 파이프라인의 경우 인라인 자리 표시자 암호를 암호화된 비밀(${{ secrets.SQL_PWD }})로 바꾸고 SQL Server 서비스 이미지를 다이제스트에 고정합니다.

Azure Pipelines

trigger:
  - main

resources:
  containers:
    - container: sqlserver
      image: mcr.microsoft.com/mssql/server:2022-latest
      env:
        ACCEPT_EULA: Y
        MSSQL_SA_PASSWORD: "<strong_password>"
      ports:
        - 1433:1433

pool:
  vmImage: ubuntu-latest

services:
  sqlserver: sqlserver

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: "3.12"

  - script: |
      curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
          sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
      echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod $(lsb_release -cs) main" | \
          sudo tee /etc/apt/sources.list.d/mssql-release.list
      sudo apt-get update
      sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev
      pip install -r requirements.txt
    displayName: Install dependencies

  - script: python manage.py test
    displayName: Run tests
    env:
      DB_HOST: "localhost"
      DB_NAME: "master"
      DB_USER: "<user_id>"
      DB_PASSWORD: "<password>"

환경 기반 settings.py

환경 변수에서 데이터베이스 자격 증명을 읽도록 구성 settings.py 합니다. 이 단일 구성은 로컬 개발, Docker 및 CI에서 작동합니다.

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "mydb"),
        "USER": os.environ.get("DB_USER", ""),
        "PASSWORD": os.environ.get("DB_PASSWORD", ""),
        "HOST": os.environ.get("DB_HOST", "localhost"),
        "PORT": os.environ.get("DB_PORT", "1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": os.environ.get("DB_EXTRA_PARAMS", "TrustServerCertificate=yes"),
        },
    },
}

로컬 개발을 위해 .env 파일에 자격 증명을 저장합니다(.env에 .gitignore 추가):

DB_HOST=localhost
DB_NAME=mydb
DB_USER=<user_id>
DB_PASSWORD=<password>

django-environ 또는 python-dotenv로 환경 변수를 로드합니다:

pip install django-environ
import environ

env = environ.Env()
environ.Env.read_env()  # Reads .env from the directory holding this settings file

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": env("DB_NAME"),
        "USER": env("DB_USER", default=""),
        "PASSWORD": env("DB_PASSWORD", default=""),
        "HOST": env("DB_HOST", default="localhost"),
        "PORT": env("DB_PORT", default="1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": env("DB_EXTRA_PARAMS", default="TrustServerCertificate=yes"),
        },
    },
}

Caution

.env 파일을 소스 제어에 커밋하지 마세요. .env 파일에 .gitignore을(를) 추가하세요.

일반적인 컨테이너 문제 해결

증상 원인 수정
Can't open lib 'ODBC Driver 18 for SQL Server' pyodbc 경로 컨테이너에 ODBC 드라이버가 설치되지 않았거나 apt-get autoremove , 설치 후에 제거된 libgssapi-krb5-2 경우. Dockerfile 또는 post-create 스크립트에 msodbcsql18를 설치하고, 그 후에는 apt-get autoremove를 실행하지 마세요.
Can't open lib 'ODBC Driver 17 for SQL Server' 버전 18을 설치할 때 버전 18은 등록되었지만 로드되지 않아 mssql-django는 설치되지 않은 버전 17로 다시 전환됩니다. 일반적인 원인은 누락 libgssapi-krb5-2. libgssapi-krb5-2을(를) 설치하고, apt-get autoremove를 제거한 후에는 curl을(를) 실행하지 마세요.
Error loading pyodbc module: libodbc.so.2 컨테이너에는 unixODBC 런타임이 없습니다. 백엔드는 Django가 pyodbc를 로드할 때 mssql-python 경로에서도 pyodbc를 가져옵니다. unixodbc를 설치하세요(또는 unixodbc-dev).
DDBC Error: Failed to load the driver mssql-python 드라이버는 자체 의존성을 로드할 수 없습니다. 설치 libkrb5-3 및 libgssapi-krb5-2.
포트 1433에서 연결이 거부됨 SQL Server 컨테이너가 준비되지 않았습니다. 상태 검사를 추가하거나 서비스가 시작될 때까지 기다립니다.
Login failed for user '<user_id>' 자격 증명이 올바르지 않거나 암호가 복잡성 요구 사항을 충족하지 않습니다. mssql-python 경로에서는 존재하지 않는 데이터베이스가 같은 메시지를 전달합니다. 컨테이너에 올바른 SQL 로그인을 사용하고 암호가 복잡성 요구 사항을 충족하는지 확인합니다. 로그인이 맞다면 데이터베이스 NAME 가 존재하는지 확인하세요.
Cannot open database 데이터베이스가 아직 존재하지 않습니다. pyodbc 경로는 이 경우를 반환하고, 대신 mssql-python 경로는 Login failed를 반환합니다. 실행 migrate하기 전에 데이터베이스를 만들거나 초기 설정에 사용합니다 master .
컨테이너의 느린 첫 번째 연결 DNS 확인 또는 자격 증명 체인 시작 로컬 SQL Server 호스트 이름 대신 사용합니다localhost.
SSL Provider: [error:0A000086] 자체 서명된 인증서를 사용한 TLS 인증서 유효성 검사 실패 TrustServerCertificate=yes에 extra_params를 개발 전용으로만 추가합니다.