Menyebarkan aplikasi Django dengan SQL Server ke Azure App Service

Artikel ini menjelaskan cara menyebarkan aplikasi Django yang menggunakan mssql-django backend untuk Azure App Service, termasuk konfigurasi driver ODBC, rahasia berbasis lingkungan, dan autentikasi identitas terkelola.

Prasyarat

  • Langganan Azure
  • Instans Azure SQL Database atau SQL Server dapat diakses dari Azure
  • Proyek Django dikonfigurasi dengan mssql-django
  • CLI Azure terpasang

Driver ODBC pada Azure App Service

Instans Azure App Service Linux menyertakan Driver Microsoft ODBC untuk SQL Server. Anda dapat memverifikasi versi driver yang diinstal dengan menjalankan:

az webapp ssh --resource-group <your-rg> --name <your-app>
odbcinst -j

Note

Azure App Service biasanya mencakup ODBC Driver 17 dan/atau 18 yang telah diinstal sebelumnya pada paket Linux. Windows App Paket layanan juga menyertakan driver ODBC.

Menggunakan variabel lingkungan untuk rahasia

Jangan menanamkan kredensial basis data langsung di settings.py. Gunakan variabel lingkungan dan konfigurasikan sebagai pengaturan aplikasi App Service:

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "USER": os.environ.get("DB_USER", ""),
        "PASSWORD": os.environ.get("DB_PASSWORD", ""),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": os.environ.get("DB_PORT", "1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Tip

Untuk nilai yang wajib ada seperti DB_NAME dan DB_HOST, pertimbangkan untuk menggunakan os.environ["DB_NAME"] (tanpa nilai default) agar aplikasi langsung gagal dengan KeyError yang jelas jika variabel lingkungan tersebut tidak ada.

Atur variabel lingkungan di Azure App Service:

az webapp config appsettings set \
    --resource-group <your-rg> \
    --name <your-app> \
    --settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net DB_USER=<your-username> DB_PASSWORD=<your-password>

Menggunakan autentikasi identitas terkelola

Untuk penyebaran produksi, gunakan identitas terkelola untuk menghindari penyimpanan kredensial. Aktifkan identitas terkelola yang ditetapkan sistem di App Service Anda:

az webapp identity assign --resource-group <your-rg> --name <your-app>

Berikan akses identitas terkelola ke database Azure SQL Anda:

CREATE USER [<your-app-name>] FOR EXTERNAL PROVIDER;

ALTER ROLE db_datareader ADD MEMBER [<your-app-name>];
ALTER ROLE db_datawriter ADD MEMBER [<your-app-name>];
ALTER ROLE db_ddladmin ADD MEMBER [<your-app-name>];

Note

Berikan hanya peran yang dibutuhkan aplikasi Anda. Peran database tetap db_ddladmin diperlukan hanya jika aplikasi menjalankan migrasi. Untuk beban kerja baca-saja, db_datareader sudah cukup.

Jika server Anda dikonfigurasi untuk autentikasi khusus Microsoft Entra, FROM EXTERNAL PROVIDER gagal dengan Msg 33130 karena server tidak dapat menjangkau Microsoft Graph untuk menyelesaikan nama identitas. Buat pengguna secara manual dengan CREATE USER [<your-app-name>] WITH SID = 0x<sid-hex>, TYPE = E, di mana <sid-hex> berasal dari ID aplikasi (klien) identitas terkelola, bukan ID objeknya. Untuk langkah-langkah konversi, lihat Memberikan akses identitas di Azure SQL.

Konfigurasikan settings.py untuk menggunakan identitas terkelola:

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryMsi",
        },
    },
}

Menggunakan token akses dengan ManagedIdentityCredential

Sebagai alternatif, gunakan pengaturan TOKEN dengan azure.identity:

Perhatian

Nilai TOKEN diambil sekali pada proses mulai dan kedaluwarsa setelah 60-90 menit. Untuk penerapan App Service jangka panjang, gunakan pendekatan ini hanya jika Anda juga menerapkan logika penyegaran token atau pendaurulangan pekerja dalam siklus singkat. Jika pola langsung ActiveDirectoryMsi berfungsi di lingkungan Anda, hal itu dapat menghindari masalah token saat startup.

import os
from azure.identity import ManagedIdentityCredential

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

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": "1433",
        "TOKEN": token,
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Tip

DefaultAzureCredentialnyaman untuk pengembangan dan basis kode bersama karena mencoba beberapa jenis kredensial secara otomatis, sehingga kode yang sama berfungsi pada laptop, di CI, dan di Azure. Namun, setiap jenis kredensial yang tidak digunakan menambah timeout beberapa detik, sehingga memperlambat proses startup. Karena App Service selalu memiliki identitas terkelola yang tersedia, ManagedIdentityCredential segera diautentikasi tanpa rantai pemeriksaan. Instal azure-identity di file persyaratan Anda: pip install azure-identity.

Jalankan migrasi selama penerapan

Tambahkan skrip pasca-penyebaran atau perintah startup untuk menjalankan migrasi secara otomatis:

az webapp config set \
    --resource-group <your-rg> \
    --name <your-app> \
    --startup-file "python manage.py migrate && gunicorn myproject.wsgi"

Mengumpulkan file statis

Konfigurasikan penanganan file statis untuk produksi:

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

Jalankan collectstatic sebagai bagian dari deployment Anda:

python manage.py collectstatic --noinput

Terapkan ke App Service

App Service dapat menghosting aplikasi Django dengan dua cara:

  • Citra Python Linux bawaan: App Service membangun kode Anda dari kode sumber dan menyediakan runtime Python.
  • Gambar Docker kustom: Anda membuat gambar sendiri dan mereferensikannya dari registri kontainer.

Kedua jalur dapat menggunakan identitas terkelola yang ditetapkan sistem untuk mengautentikasi ke Azure SQL, tetapi resepnya berbeda. Pilih tab yang cocok dengan penyebaran Anda.

Dengan gambar Python Linux bawaan, pembuat Oryx App Service menginstal requirements.txt dan memulai aplikasi Django Anda di bawah gunicorn secara otomatis. Proksi HTTP identitas terkelola lokal membuat Authentication=ActiveDirectoryMsi berfungsi langsung dari string koneksi ODBC. Gunakan settings.py yang ditampilkan di Gunakan autentikasi identitas terkelola.

Sebarkan kode Anda dengan az webapp up, aktifkan identitas terkelola yang ditetapkan sistem, dan atur variabel lingkungan database:

az webapp up \
    --resource-group <your-rg> \
    --name <your-app> \
    --runtime "PYTHON:3.12" \
    --sku B1

az webapp identity assign --resource-group <your-rg> --name <your-app>

az webapp config appsettings set \
    --resource-group <your-rg> \
    --name <your-app> \
    --settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net

Kemudian berikan akses identitas terkelola di SQL seperti yang dijelaskan dalam Menggunakan autentikasi identitas terkelola.

Pengembangan lokal dengan Docker Compose

Untuk pengembangan dan pengujian lokal, gunakan Docker Compose untuk menjalankan aplikasi Django Anda bersama kontainer SQL Server:

# docker-compose.yml
services:
  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      MSSQL_SA_PASSWORD: "<password>"  # Must meet SQL Server complexity requirements
    ports:
      - "1433:1433"

  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      DB_HOST: db
      DB_NAME: mydb
      DB_USER: sa
      DB_PASSWORD: "<password>"
    depends_on:
      - db

Tip

Kontainer SQL Server tidak membuat database aplikasi secara otomatis. Setelah memulai kontainer, buat database dan jalankan migrasi:

docker compose exec db /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "<password>" -No -Q "CREATE DATABASE mydb"
docker compose exec web python manage.py migrate

Gambar kontainer SQL Server memerlukan ACCEPT_EULA=Y dan kata sandi SA yang kuat. Untuk lingkungan produksi, gunakan Azure SQL Database dengan identitas terkelola alih-alih kredensial SQL Server. Lihat Menggunakan autentikasi identitas terkelola.