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

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

사전 요구 사항

  • Python 3.8 이상(Django 6.0에는 Python 3.12 이상 버전 필요)
  • Docker Desktop(컨테이너 기반 개발용)
  • Microsoft SQL Server용 ODBC 드라이버 17 또는 18. SQL Server ODBC 드라이버 다운로드를 참조하세요.

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=YourStr0ngP@ssword" \
  -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

SQL Server 연결하는 Django 애플리케이션에 대한 최소 Dockerfile을 만듭니다. ODBC 드라이버는 Python 기본 이미지와 함께 제공되지 않는 주요 종속성입니다.

FROM python:3-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 && \
    apt-get autoremove -y && \
    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"]

귀하의 requirements.txt:

django>=5.2
mssql-django>=1.5
gunicorn>=22.0

빌드 및 실행:

docker build -t mydjango .
docker run -e DB_HOST=host.docker.internal -e DB_NAME=mydb \
  -e DB_USER=<your-username> -e DB_PASSWORD=<your-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"
            ]
        }
    }
}

이 devcontainer는 ODBC 드라이버 및 Python 종속성을 설치하지만 SQL Server 인스턴스는 포함하지 않습니다. Docker-in-Docker를 사용할 수 있으므로 sqlcmd create mssql --accept-eula를 사용해 devcontainer 내부에서 SQL Server 인스턴스를 시작하거나, 기본 제공 SQL Server 서비스를 사용하려면 Docker Compose 방식을 사용하세요.

ODBC 드라이버와 Python 종속성을 설치하려면 .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: "YourStr0ngP@ssword"
    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을 대상으로 로컬 개발을 할 때는 OPTIONS["extra_params"](mssql-django 1.7.3 이상 및 호환되는 Microsoft ODBC Driver 포함)에서 Authentication=ActiveDirectoryDefault를 사용하거나, DefaultAzureCredential와 함께 TOKEN 설정을 사용하세요. 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": "myserver.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": "myserver.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: YourStr0ngP@ssword
        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.x"

      - name: Install ODBC Driver
        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: <username>
          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: YourStr0ngP@ssword
      ports:
        - 1433:1433

pool:
  vmImage: ubuntu-latest

services:
  sqlserver: sqlserver

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: "3.x"

  - 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: <username>
      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 파일에 자격 증명을 저장합니다(.gitignore.env 추가):

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

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

pip install django-environ
import environ

env = environ.Env()
environ.Env.read_env()  # Reads .env 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",
        },
    },
}

Caution

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

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

증상 원인 수정
Can't open lib 'ODBC Driver 18 for SQL Server' 컨테이너에 ODBC 드라이버가 설치되지 않았습니다. Dockerfile 또는 post-create 스크립트에 msodbcsql18를 설치하세요.
포트 1433에서 연결이 거부됨 SQL Server 컨테이너가 준비되지 않았습니다. 상태 검사를 추가하거나 서비스가 시작될 때까지 기다립니다.
Login failed for user '<username>' 자격 증명이 올바르지 않거나 암호가 복잡성 요구 사항을 충족하지 않습니다. 컨테이너에 올바른 SQL 로그인을 사용하고 암호가 복잡성 요구 사항을 충족하는지 확인합니다.
Cannot open database 데이터베이스가 아직 존재하지 않습니다. 실행 migrate하기 전에 데이터베이스를 만들거나 초기 설정에 사용합니다 master .
컨테이너의 느린 첫 번째 연결 DNS 확인 또는 자격 증명 체인 시작 로컬 SQL Server 호스트 이름 대신 사용합니다localhost.
SSL Provider: [error:0A000086] 자체 서명된 인증서를 사용한 TLS 인증서 유효성 검사 실패 extra_paramsTrustServerCertificate=yes를 개발 전용으로만 추가합니다.