Gitlab CI CD - ASPNET Core 배포 및 DB Migration

2023. 9. 4. 00:00DevOps/GitLab CI CD

반응형
...
    docker stop $CONTAINER_NAME 2 2> /dev/null
    docker rm $CONTAINER_NAME 2 2> /dev/null
    docker rmi $IMAGE_NAME 2> /dev/null
...

지난 강좌에서 아주 기본적인 Gitlab runner 를 이용한 CI CD 를 알아보았다. 

이번에 aspnet 으로 만들어진 web api 를 배포 하고

ef core 의 bundle migration 을 이용하여 db 까지 migration 및 update 하는 방법을 알아보겠다. 

 

일단 EF Core 를 이용하여 bundle 을 생성하자.

자신의 runner 의 설치 platform 을 기준으로 작업하자

(windows 라면 win-64,  linux 라면 linux-64)

// linux-64
dotnet ef migrations bundle --project Infrastructure --startup-project IdentityServer --context MySqlContext --self-contained -r linux-x64 -v -o ./IdentityServer/efbundle.exe -f
// win-64
dotnet ef migrations bundle --project Infrastructure --startup-project IdentityServer --context MySqlContext --self-contained -r win-x64 -v -o ./IdentityServer/efbundle.exe -f

Gitlab pipeline

variables:
  CONTAINER_NAME: $CONTAINER_NAME
  IMAGE_NAME: $IMAGE_NAME
  DB_CONNECTION_STRING: $DB_CONNECTION_STRING
  
before_script:
  - |
    $RUNNING_CONTAINER_ID = (docker ps -aq -f "name=$CONTAINER_NAME")
    if ($RUNNING_CONTAINER_ID) { 
      echo "Stopping and removing container: $RUNNING_CONTAINER_ID"
      docker stop $RUNNING_CONTAINER_ID 
      docker rm $RUNNING_CONTAINER_ID 
      docker rmi identity-server
    } else {
      echo "No running container with name $CONTAINER_NAME found."
    }
  - cd IdentityServer
  - echo "Running before script..."
  - dotnet restore
  - echo "Running efbundle..."
  - echo $CONTAINER_NAME
  - echo $DB_CONNECTION_STRING
  - .\efbundle.exe --connection $DB_CONNECTION_STRING
  - cd ..
  - ls

stages:          # List of stages for jobs, and their order of execution
  - build

docker_build:
  stage: build
  script:
    - echo "docker building the code..."
    - docker buildx build -t $IMAGE_NAME -f Dockerfile .
    - docker run --name $CONTAINER_NAME -d --restart unless-stopped -p 5005:80 $IMAGE_NAME
    - echo "docker build complete."

각 variable 은 settings-->CI/CD-->Variables-->Add variable 를 이용해 입력한 후 사용한다.

그런데 위와 같이 작업 하려면 일단 mysql 이 host 에 설치되어 있는 상태여야 한다. 

(host.docker.internal 를 통해 host 의 localhost 로 docker container 상에 app 이 접근 가능하다.)

 

만약 연결하려는 my sql 도 container 로 실행 시켰다면 같은 network 상에 동작하도록 해야 한다. 

docker network create my_network

그리고 my sql container 를 실행 중지 시키고 다음과 같이 실행 시켜 보자

docker stop <containerid>
docker container rm <containerid>
docker run -d --restart unless-stopped --name mysql-container -e MYSQL_ROOT_PASSWORD=1234  -p 3306:3306 --network my_network <mysql iamge>

이제 Gitlab 의 pipeline editor 에서 docker run 시에 다음과 같이 수정 하자

variables:
  CONTAINER_NAME: $CONTAINER_NAME
  IMAGE_NAME: $IMAGE_NAME
  DB_CONNECTION_STRING: $DB_CONNECTION_STRING
  DB_CONNECTION: $DB_CONNECTION
  
before_script:
  - |
    $RUNNING_CONTAINER_ID = (docker ps -aq -f "name=$CONTAINER_NAME")
    if ($RUNNING_CONTAINER_ID) { 
      echo "Stopping and removing container: $RUNNING_CONTAINER_ID"
      docker stop $RUNNING_CONTAINER_ID 
      docker rm $RUNNING_CONTAINER_ID 
      docker rmi identity-server
    } else {
      echo "No running container with name $CONTAINER_NAME found."
    }
  - cd IdentityServer
  - echo "Running efbundle..."
  - echo $CONTAINER_NAME
  - echo $DB_CONNECTION_STRING
  - .\efbundle.exe --connection $DB_CONNECTION_STRING
  - cd ..
  - ls

stages:          # List of stages for jobs, and their order of execution
  - build


docker_build:
  stage: build
  script:
    - echo "docker building the code..."
    - docker buildx build -t $IMAGE_NAME -f Dockerfile .
    - docker run 
      -e ConnectionStrings__Server=$DB_CONNECTION 
      --name $CONTAINER_NAME -d --restart unless-stopped -p 5005:80 
      --network my_network $IMAGE_NAME
    - echo "docker build complete."

그런데 위 if 문 없이 체크 하는 방법은 없을까?

물론 있다.  powershell 이므로 다음과 같이 수정한다. 

[command] 2 > &null;$true  로 처리한다.

before_script:
  - |
    echo "Stopping and removing container:" $CONTAINER_NAME
    docker stop $CONTAINER_NAME 2>$null;$true 
    docker rm $CONTAINER_NAME 2>$null;$true 
    docker rmi $IMAGE_NAME 2>$null;$true 
  - cd IdentityServer
  - echo "Running efbundle..."
  - echo $CONTAINER_NAME
  - echo $DB_CONNECTION_STRING
  - .\efbundle.exe --connection $DB_CONNECTION_STRING
  - cd ..\UnitTest
  - dotnet test -e ConnectionStrings__Server=$DB_CONNECTION_STRING
  - cd ..
  - ls

linux 는 다음과 같다.

...
    docker stop $CONTAINER_NAME 2> /dev/null || true 
    docker rm $CONTAINER_NAME 2> /dev/null || true 
    docker rmi $IMAGE_NAME 2> /dev/null || true 
...

windows 에서 command 라인을 shell 로 쓴다면 다음과 같다. 

...
    docker stop $CONTAINER_NAME > nul 2>&1 || exit 0
    docker rm $CONTAINER_NAME > nul 2>&1 || exit 0
    docker rmi $IMAGE_NAME > nul 2>&1 || exit 0
...

 

관련영상

https://youtu.be/DJ4WPbvdxno

반응형