All Articles

AWS CodeBuild에서 사이드카로 MySQL를 띄우기

Django나 Spring 등의 애플리케이션을 테스트하는 경우 MySQL나 Redis 등의 데이터베이스가 필요합니다. 물론 SQLite나 H2 등의 임베디드 데이터베이스를 사용하면 별도로 데이터베이스를 설정할 필요는 없습니다. 그러나 RDBMS 별로 동작이 모두 다르기 때문에, SQLite에서 테스트가 성공했다고 MySQL에서 테스트가 성공할 것이라고는 보장할 수 없습니다. (예를 들어, UNIQUE 속성과 NULL 속성을 동시에 주면, MySQL에서는 NULL 값이 여러 개 들어가는 것이 허용되지만 PostgreSQL에서는 허용되지 않습니다) 그래서 실제 서비스에서 사용하는 데이터베이스를 이용해 테스트를 진행합니다.

기존에는 Jenkins 인스턴스에 MySQL 서버를 설치하여 사용했습니다. 인스턴스가 테스트 중 자꾸 죽어버리는 이슈가 있어 이를 CodeBuild로 마이그레이션하였습니다. 마이그레이션 중 CodeBuild는 Docker 기반으로 돌아가는 것에 착안하여, MySQL를 사이드카 패턴으로 띄우는 데 성공했습니다. 사실 안될 줄 알았는데 테스트 해 보니 잘 되더라구요.

CodeBuild에서 Docker Daemon에 접근하려면, Privileged 권한이 필요합니다. 체크해주도록 합시다.

version: 0.2

phases:
  build:
    commands:
      # develop이나 master 브랜치로 merge 후 테스트를 진행하려면 아래 주석 해제
      # - git merge --no-edit "$CODEBUILD_WEBHOOK_BASE_REF"

      # 커스텀 도커 이미지에서 시작한다면 아래 명령 필요
      # - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay&
      # - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"

      # MySQL 5.7 버전을 사이드카 패턴으로 띄운다
      - docker run -d -e MYSQL_ROOT_PASSWORD=root --name=mysql mysql:5.7 mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci

      # MySQL IP를 가져온다
      - MYSQL_HOST="$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql)"
      
      # MySQL이 뜰 때까지 기다린다
      - timeout 30 docker run mysql:5.7 sh -c "while ! timeout 0.5 mysqladmin ping -uroot -proot -h $MYSQL_HOST ; do sleep 0.5; done"
      
      # 현재 빌드 컨텍스트에서 접근해 본다
      - apt update && apt install -y mysql-client
      - mysql -uroot -proot -h "$MYSQL_HOST" -e "create database test_db"
      - mysql -uroot -proot -h "$MYSQL_HOST" test_db -e "select 1"

위의 예시에서는 MySQL를 예시로 들었는데, 위 동일한 방법으로 PostgreSQL이나 Redis 등의 다른 DBMS들도 동시에 띄울 수 있습니다.

Jenkins를 사용할 때에는 이유를 알 수 없는 MySQL Crash 등의 문제가 자주 일어났는데, CodeBuild로 마이그레이션을 진행한 후에는 테스트 호스트 인스턴스가 망가져서 테스트가 깨지는 문제가 사라졌습니다. CodeBuild 짱짱.