배포: 시나리오: Azure App Service + Github + SQL Server

발행: (2026년 1월 9일 오전 08:07 GMT+9)
11 분 소요
원문: Dev.to

Source: Dev.to

우리가 구성할 시나리오의 구성 요소

  • Azure App Service: 애플리케이션이 실행되는 곳
  • GitHub: 코드가 저장되는 곳
  • GitHub Actions (선택 사항이지만 권장): 빌드 및 배포 자동화
  • Azure SQL Database (SQL Server): 데이터가 저장되는 곳
GitHub (código)

Pipeline (build / deploy)

Azure App Service (API / App)

Azure SQL Database (dados)

1. Azure App Service란?

이미 서버 유형에 대해 살펴본 바와 같이, Azure App Service는 관리형 서비스입니다. 이는 다음을 의미합니다:

  • 서버를 직접 만들지 않음
  • Windows/Linux를 직접 설치하지 않음
  • IIS, Kestrel 또는 Nginx를 수동으로 구성하지 않음

1.1 App Service

Azure 플랫폼이 이러한 모든 문제를 대신 처리합니다. App Service를 만들 때 다음을 정의합니다:

  • 런타임 (예: .NET 8)
  • 호스팅 플랜 (CPU / 메모리 / 비용)
  • 리전 (서버가 위치하는 곳)

그 결과 공개 URL과 코드를 실행할 준비가 된 환경이 제공됩니다:

https://minha-api.azurewebsites.net

중요: 이 시점에서는 아직 실행 중인 코드는 없습니다.

1.2 코드가 Azure에 어떻게 올라가나요? (GitHub Actions)

Azure App Service가 설정된 후, 코드를 리포지토리에서 Azure로 올려야 합니다. 여기서는 GitHub Actions를 사용하고, 이 도구가 해결하는 문제를 살펴보겠습니다.

1.2.1 수동 프로세스

GitHub Actions 이전에 배포는 보통 다음과 같이 진행되었습니다:

  1. 로컬에서 컴파일
  2. 수동으로 배포
  3. FTP를 통해 파일 덮어쓰기

이 프로세스는 일관성 부족, 인간 실수, 히스토리 부재, 예측 불가능한 배포와 같은 문제를 야기합니다.

1.2.2 GitHub Actions

GitHub Actions는 구성 가능한 로봇으로, 리포지토리에서 무언가가 발생할 때마다 GitHub 내부에서 실행됩니다. 이 “무언가”는 다음과 같습니다:

  • push
  • pull request
  • 태그 생성
  • 예약된 시간

이 로봇은 코드를 컴파일하고, 테스트를 실행하고, 빌드를 생성하고, 배포하고, 알림을 보내는 등 다양한 작업을 수행할 수 있습니다. 모든 작업은 워크플로우가 설정되어 있기 때문에 가능합니다.

1.3 워크플로우란 무엇이며 이것과 어떤 관련이 있나요?

워크플로우는 .yml 파일로, “X가 발생하면 Y 단계를 순서대로 실행한다”는 내용을 기술합니다. 예시:

# .github/workflows/deploy.yml
on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Build
        run: dotnet build --configuration Release
      - name: Test
        run: dotnet test --no-build --configuration Release
      - name: Publish
        run: dotnet publish -c Release -o ./publish
      - name: Deploy to Azure
        uses: azure/webapps-deploy@v2
        with:
          app-name: minha-api
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: ./publish

이점: 워크플로우 파일 자체가 코드이므로, 배포가 버전 관리, 감사 가능, 재현 가능해집니다.

2. Azure에서 SQL Server 만들기

Azure에서 데이터베이스를 만들면 자동 백업, 고가용성 및 설치가 필요 없습니다. 프로세스가 끝나면 다음을 받게 됩니다:

  • 서버 이름
  • 데이터베이스 이름
  • 사용자 이름 및 비밀번호

이 정보는 절대로 코드에 포함되어서는 안 됩니다.

2.1 논리 서버 (SQL Server)

VM이 아니라 인증 및 연결을 위한 관리형 엔드포인트입니다. 서버는:

  • 여러 데이터베이스를 호스팅할 수 있음
  • 보안을 중앙 집중화
  • 방화벽을 제어

Azure 포털에서:
Azure SQL → Create → 입력:

  • Server namemeu-servidor.database.windows.net
  • Admin login
  • 비밀번호

2.2 데이터베이스

서버 내에서 nomeDoBanco 데이터베이스를 만들고 다음을 정의합니다:

  • 계층 (Basic / General Purpose / Business Critical)
  • DTU 또는 vCore

2.3 SQL Server 방화벽

기본적으로 아무도 데이터베이스에 접근할 수 없습니다. Networking → Firewall rules에서 구성하세요:

  • ✔️ Allow Azure services
  • ✔️ Adicionar IP da sua máquina (로컬 마이그레이션용)

이렇게 하지 않으면:

  • 애플리케이션이 연결되지 않음
  • 마이그레이션 실패
  • 타임아웃 오류

실제 프로덕션에서는: Private Endpoint를 사용하는 것이 이상적입니다. 시작 단계에서는 간단한 방화벽 설정만으로도 충분합니다.

Source:

3. Connection String – 애플리케이션과 데이터베이스를 연결하는 방법

이는 전체 배포 과정에서 가장 중요한 부분 중 하나입니다. Connection string이 없으면 애플리케이션이 데이터베이스와 통신하지 못합니다.

  • 애플리케이션 시작: ✔️
  • 데이터베이스 존재: ✔️
  • 하지만 아무것도 통신되지 않음:

3.1 Azure SQL Database에서 이미 만든 항목

  • 서버 이름
  • 데이터베이스 이름
  • 관리자 로그인
  • 비밀번호
  • 인증 유형 (SQL Authentication)

이 정보들이 Connection string의 기본이 됩니다.

3.2 실제로 Connection String이란?

애플리케이션에 다음 정보를 알려 주는 텍스트입니다.

  • 데이터베이스가 어디에 있는지
  • 어떤 데이터베이스에 접속할지
  • 어떻게 인증할지
  • 연결 중에 어떻게 동작할지

일반적인 예시:

Server=...
Database=...
User Id=...
Password=...

3.3 Connection String 값은 어디서 오는가?

Azure SQL Database에서:

SQL Database → Settings → Connection strings

보통 다음과 같은 형태를 볼 수 있습니다.

Server=tcp:meuservidor.database.windows.net,1433;
Initial Catalog=MinhaBase;
PersistSecurityInfo=False;
User ID=adminuser;
Password=********;
MultipleActiveResultSets=False;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;

팁: 전체 문자열을 복사하여 Secret(예: Azure Key Vault 또는 GitHub Secrets)에 저장해 두면 코드에 노출되지 않습니다.

3.4 이제 앱 → 데이터베이스 연결하기

이 설정은 Azure App Service에서 직접 수행되며, 코드를 수정할 필요가 없습니다.

3.4.1 Azure Portal 경로

App Service
 → Settings
 → Configuration
 → Connection strings

이 영역은 애플리케이션의 비밀 저장소 역할을 합니다.

  • ✅ 더 안전함
  • ✅ 코드와 분리됨
  • ✅ 환경별(Dev / Staging / Production) 사용에 적합

3.4.2 Connection String 이름 (매우 중요)

Entity Framework Core를 사용하는 경우 가장 일반적이고 권장되는 이름은:

DefaultConnection

이 이름은 Program.cs 또는 appsettings.json에 정의된 이름과 정확히 일치해야 합니다.

코드 예시:

builder.Services.AddDbContext(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

Azure에서 이름이 다르면:

  • ❌ 애플리케이션은 시작됨
  • ❌ 하지만 데이터베이스를 찾지 못함
  • ❌ 전형적인 오류: The ConnectionString property has not been initialized

4. 마이그레이션

이제 데이터베이스 배포에서 가장 중요한 부분이 나옵니다. 세 가지 실용적인 흐름으로 나누어 보겠습니다:

  • 수동 마이그레이션 로컬 → Azure SQL
  • GitHub Actions를 통한 마이그레이션 → Azure SQL (파이프라인)
  • SQL 스크립트 마이그레이션 (기업에서 사용하는 실무)

4.1 수동 마이그레이션 (로컬 → Azure SQL)

전제 조건

  • EF Core 프로젝트
  • 이미 생성된 마이그레이션

이는 아직 데이터베이스를 변경하지 않고, C# 파일만 생성합니다.

4.2 Azure에서 데이터베이스 접근 허용

기본적으로 Azure SQL은 모든 접근을 차단하므로 로컬 머신을 허용해야 합니다; 이를 하지 않으면 시스템에서 Login failed / Timeout expired 오류가 발생합니다.

Azure 포털에서

  1. Azure SQL Server
  2. 네트워킹
  3. 방화벽 규칙
  4. 클라이언트 IPv4 주소 추가
  5. 저장

4.3 애플리케이션이 Azure를 가리키도록 보장

appsettings.Development.json 파일이 Azure의 SQL Server를 가리키고 있는지 확인하세요:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=tcp:meuservidor.database.windows.net;..."
  }
}

4.4 마이그레이션 실행

dotnet ef database update

내부에서 일어나는 일

  • EF가 Azure SQL에 연결을 엽니다
  • __EFMigrationsHistory 테이블이 존재하는지 확인합니다
    • 존재하지 않으면 → 생성
    • 존재하면 → 이미 실행된 마이그레이션을 읽습니다
  • 비교합니다:
    • 코드에 있는 마이그레이션
    • 데이터베이스에 있는 마이그레이션
  • 보류 중인 것만 실행합니다
  • 적용된 버전을 기록합니다
Back to Blog

관련 글

더 보기 »

안녕, 뉴비 여기요.

안녕! 나는 다시 S.T.E.M. 분야로 돌아가고 있어. 에너지 시스템, 과학, 기술, 공학, 그리고 수학을 배우는 것을 즐겨. 내가 진행하고 있는 프로젝트 중 하나는...