Kontainer dan pengembangan lokal dengan mssql-django

Panduan ini mencakup pengaturan lingkungan untuk pengembang Django yang bekerja dengan mssql-django backend di Windows, Linux, macOS, kontainer Docker, devcontainers, dan alur CI.

Prasyarat

  • Python 3.8 atau yang lebih baru (Django 6.0 memerlukan Python 3.12 dan versi yang lebih baru)
  • Docker Desktop (untuk pengembangan berbasis kontainer)
  • Microsoft ODBC Driver 17 atau 18 untuk SQL Server. Lihat Mengunduh Driver ODBC untuk SQL Server.

Utilitas sqlcmd (Go) dapat membuat kontainer SQL Server dalam satu perintah. Ini menangani penarikan gambar Docker, pembuatan kata sandi, penetapan port, dan konteks koneksi secara otomatis:

sqlcmd create mssql --accept-eula

Untuk membuat kontainer dengan database sampel yang sudah dilampirkan:

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

Setelah pembuatan, sqlcmd simpan konteks koneksi sehingga Anda dapat segera mengkueri:

sqlcmd query "SELECT @@VERSION"

Konfigurasikan Django agar terhubung menggunakan detail koneksi yang sqlcmd tampilkan saat dibuat. Gunakan sqlcmd config view untuk mengambilnya nanti:

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",
        },
    },
}

Setelah selesai, hentikan atau hapus kontainer:

sqlcmd stop
sqlcmd delete

Tip

Jalankan sqlcmd create mssql --user-database mydb untuk membuat kontainer dengan database pengguna kosong yang siap untuk pengembangan.

SQL Server lokal di Visual Studio Code

Ekstensi MSSQL untuk Visual Studio Code dapat membuat kontainer SQL Server lokal langsung dari editor:

  1. Buka tampilan SQL Server di Bilah Aktivitas.
  2. Pilih Tambahkan Koneksi>Buat SQL Server Lokal (atau gunakan Palet Perintah: MS SQL: Buat SQL Server Lokal).
  3. Pilih versi SQL Server dan terima EULA.
  4. Ekstensi menarik gambar kontainer, menghasilkan kata sandi, dan menambahkan profil koneksi secara otomatis.

Setelah kontainer berjalan, Anda dapat menelusuri database, menjalankan kueri, dan mengelola objek di Visual Studio Code sebelum beralih ke kode Django Anda.

SQL Server lokal dengan Docker

Jika Anda lebih suka mengelola kontainer secara langsung, gambar kontainer resmi SQL Server berfungsi dengan dua variabel lingkungan:

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

Gunakan MSSQL_SA_PASSWORD untuk kontainer SQL Server. Variabel lama SA_PASSWORD tidak digunakan lagi. Kata sandi harus memenuhi persyaratan kompleksitas SQL Server: setidaknya 8 karakter, dengan huruf besar, huruf kecil, digit, dan karakter khusus.

Tunggu beberapa detik hingga kontainer dimulai, lalu jalankan migrasi:

python manage.py migrate
python manage.py createsuperuser

Dockerfile untuk aplikasi Django

Buat Dockerfile minimal untuk aplikasi Django yang terhubung ke SQL Server. Driver ODBC adalah dependensi utama yang tidak disertakan dengan gambar dasar 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 Anda:

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

Bangun dan jalankan:

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

Note

Gunakan host.docker.internal di Docker Desktop (Windows dan macOS) untuk mencapai SQL Server di komputer host. Di Linux, gunakan --network host sebagai gantinya.

Menyiapkan Devcontainer

Buat .devcontainer/devcontainer.json untuk Visual Studio Code yang menyertakan SQL Server sebagai layanan sidecar:

{
    "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 ini menginstal driver ODBC dan dependensi Python tetapi tidak menyertakan instans SQL Server. Mulai satu di dalam devcontainer menggunakan sqlcmd create mssql --accept-eula (karena Docker-in-Docker tersedia) atau gunakan pendekatan Docker Compose untuk layanan SQL Server bawaan.

Buat .devcontainer/post-create.sh untuk menginstal driver ODBC dan dependensi Python:

#!/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

Sertakan SQL Server dengan Docker Compose

Untuk menyertakan SQL Server sebagai layanan di devcontainer, gunakan 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 (Buat versi):

{
    "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"
            ]
        }
    }
}

Sambungkan Django ke layanan SQL Server berdasarkan nama:

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",
        },
    },
}

Autentikasi untuk pengembangan

Pilih pendekatan autentikasi berdasarkan tempat aplikasi Anda berjalan dan tempat database dihosting.

Pengembangan lokal terhadap Azure SQL

Untuk pengembangan lokal untuk Azure SQL, gunakan salah satu Authentication=ActiveDirectoryDefault di OPTIONS["extra_params"] (dengan mssql-django versi 1.7.3 dan yang lebih baru, serta Microsoft ODBC Driver yang kompatibel) atau setelan TOKEN dengan DefaultAzureCredential. DefaultAzureCredential secara otomatis melanjutkan sesi Anda 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",
        },
    },
}

Untuk matriks autentikasi lengkap dan perhatian, lihat autentikasi Microsoft Entra dengan mssql-django.

Pengembangan kontainer terhadap Azure SQL

Untuk kontainer yang berjalan di Azure, gunakan pengaturan TOKEN dengan ManagedIdentityCredential untuk memperoleh token akses Microsoft Entra secara eksplisit:

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",
    },
  },
}

Untuk daftar lengkap metode autentikasi, lihat Microsoft Entra autentikasi dengan mssql-django.

Penyiapan alur CI

Jalankan rangkaian pengujian Django Anda terhadap kontainer layanan SQL Server di alur CI Anda.

GitHub Actions

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

Untuk alur bersama, ganti kata sandi tempat penampung sebaris dengan rahasia terenkripsi (${{ secrets.SQL_PWD }}) dan sematkan gambar layanan SQL Server ke hash.

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 berdasarkan lingkungan

Konfigurasikan settings.py untuk membaca kredensial database dari variabel lingkungan. Konfigurasi tunggal ini berfungsi di seluruh pengembangan lokal, Docker, dan 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"),
        },
    },
}

Simpan kredensial dalam .env file untuk pengembangan lokal (tambahkan .env ke .gitignore):

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

Muat variabel lingkungan dengan django-environ atau 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",
        },
    },
}

Perhatian

Jangan pernah menerapkan .env file ke kontrol sumber. Tambahkan .env ke file Anda .gitignore .

Memecahkan masalah umum kontainer

Gejala Cause Perbaiki
Can't open lib 'ODBC Driver 18 for SQL Server' Driver ODBC tidak diinstal dalam kontainer. Instal msodbcsql18 di Dockerfile atau skrip pasca-buat Anda.
Koneksi ditolak pada port 1433 SQL Server kontainer belum siap. Tambahkan pemeriksaan kesehatan atau tunggu layanan dimulai.
Login failed for user '<username>' Kredensial salah atau kata sandi tidak memenuhi persyaratan kompleksitas. Gunakan login SQL yang benar untuk kontainer Anda, dan pastikan kata sandi memenuhi persyaratan kompleksitas.
Cannot open database Database belum ada. Buat database sebelum menjalankan migrate, atau gunakan master untuk penyiapan awal.
Koneksi pertama yang lambat di dalam kontainer Inisialisasi resolusi DNS atau rantai kredensial. Untuk SQL Server lokal, gunakan localhost alih-alih nama host.
SSL Provider: [error:0A000086] Kegagalan validasi sertifikat TLS dengan sertifikasi yang ditandatangani sendiri. Tambahkan TrustServerCertificate=yes ke extra_params untuk pengembangan saja.