Docker Compose 서비스를 시작하기 전에 SQL 마이그레이션 실행

10977 단어 sqldevopsdocker

Want more great content like this? Sign up for my newsletter, visit: alec.coffee/signup


좋은 현지 개발 경험을 가지고 있는 것은 즐거운 엔지니어에게 매우 중요하다.개발자들은 노트북을 들을까 봐 두려워하지 않고 코드 라이브러리에 들어가 문제를 풀기 시작했다.서비스가 점점 단독의'마이크로서비스'로 분리되면서 새로운 문제가 생겼다.내가 짧은 직업 생활을 돌이켜 볼 때, 나를 고통스럽게 하는 문제는 SQL 이전과 그것들이 Docker Compose에서 어떻게 일해야 하는가이다.이상적인 상황에서 네트워크 응용 프로그램이 시작되기 전에 실행해야 구조가 좋은 데이터베이스에 접근할 수 있다.이 목표를 실현하는 전략은 환경에 따라 다를 수 있습니다. 이 글에서 저는 당신의 현지 경험을 소개할 것입니다. 이러한 경험은 CI로 쉽게 확장될 수 있습니다. 저는 어떻게 생산에서 이 점을 할 수 있는지 토론할 것입니다.

약간의 배경 지식


우리가 창고에서 채택하기 시작했을 때 Apollo Federation 나는 이 문제에 부딪혔다.하나의 게이트웨이 서비스는 다른 GraphQL 서비스 이전에 있습니다.이 게이트웨이는 클라이언트 응용 프로그램(그림의 웹 브라우저)에서 데이터를 얻기 위해 조회하는 게이트웨이입니다.클라이언트가 게이트웨이 API를 사용하기 시작하려면 모든 관련 서비스가 정상적으로 실행되어야 합니다.

나의 목표는 모든 서비스가 의존하는 서비스가 정상적으로 실행될 때까지 확실한 방식으로 전체 서비스 집합을 시작하는 것이다.본고에서 나는 데이터베이스와 이전을 중점적으로 소개할 것이지만 이곳의 개념은 다른 서비스에 의존하는 모든 서비스로 확대되었다.
제품 서비스 및 마이그레이션을 실행하는 일반적인 Docker Compose 파일은 다음과 같습니다.
version: "3.7"

postgres:
  image: yourorg/postgres
  command: postgres -c 'max_connections=1024'
  expose:
    - "5432"
  environment:
    POSTGRES_USER: ${DATABASE_USERNAME}
    POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
  volumes:
    - ${YOUR_ORG_INSTALL_PATH}/volumes/services/postgres-data:/var/lib/postgresql/data:delegated

products-run-migrations:
  build:
    context: ./apps/products/migrations/.
  image: yourorg/products-run-migrations:${IMAGE_TAG:-latest}
  env_file:
    - ./apps/products/products.env
  depends_on:
    - postgres

products:
  build:
    context: ./apps/products/.
  image: yourorg/products:${IMAGE_TAG:-latest}
  env_file:
    - ./apps/products/products.env
  depends_on:
    - postgres
    - products-run-migrations
이 설정의 몇 가지 문제점 depends_on:
  • products-run-migrations 스크립트는 postgres가 정상적으로 작동하고 연결을 받을 준비가 되어 있지 않은 상태에서 실행됩니다.마이그레이션이 시작되었을 때 postgres 용기의 99퍼센트가 정상적이지 않아 마이그레이션에 실패했을 가능성이 있습니다.
  • products 서비스와 유사하며, products-run-migrations 서비스를 시작할 때 정확하게 실행됩니다.products 서비스가 정상적일 때 이 서비스를 조회하면 이전이 완료되지 않을 가능성이 높습니다.
  • 뭐 공부 해요?


    이것은 우리가 현재 원하는 것이 아니다. 이상적인 상황에서 개발자는 제품 서비스를 시작할 수 있어야 한다. 정상적으로 실행될 때 이전이 성공적으로 실행되었음을 알고 API를 조회할 수 있어야 한다.

    이것은 내가 약간의 연구를 해야 한다.
    나는 conditions 매개 변수가 우리가 원하는 실현을 실현할 수 있다는 것을 발견했다.하지만 내가 발견한 다음 일은 일이 어디에서 통제력을 잃었다는 것이다.
    dockercompose 버전을 내려야 합니다.
    Turns out, Docker Compose 3.x versions are meant to be used for Docker Swarm and Kubernetes environments where services are not strictly dependent on each other. 이것은 서비스가 독립적으로 운행하는 더욱 용착된 환경을 촉진시켰다.
    What I saw people suggesting Docker Compose 2.4로 전환하고 유사한 포트 대기 스크립트를 사용합니다.
    새 Docker Compose 2.4 파일:
    version: '2.4'
    
    postgres:
      image: yourorg/postgres
      command: postgres -c 'max_connections=1024'
      expose:
        - '5432'
      environment:
        POSTGRES_USER: ${DATABASE_USERNAME}
        POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      volumes:
        - ${YOUR_ORG_INSTALL_PATH}/volumes/services/postgres-data:/var/lib/postgresql/data:delegated
      healthcheck:
        test: ['CMD-SHELL', 'pg_isready -U root']
        interval: 60s
    
    products-run-migrations:
      build:
        context: ./apps/products/migrations/.
      image: yourorg/products-run-migrations:${IMAGE_TAG:-latest}
      entrypoint:
          - /bin/bash
          - -c
          - 'wait-for-it $$DATABASE_HOSTNAME:5432 -s -t 60 -- npm run db-migrate:products
      restart: on-failure:5
      env_file:
        - ./apps/products/products.env
      depends_on:
          postgres:
            condition: service_healthy
    
    products:
      build:
        context: ./apps/products/.
      image: yourorg/products:${IMAGE_TAG:-latest}
      env_file:
        - ./apps/products/products.env
      restart: on-failure:5
      depends_on:
          postgres:
            condition: service_healthy
          products-run-migrations:
            condition: service_started
    
    몇 가지 새로운 보충:
  • 용기에 depends_on 를 추가했습니다.이 때문에 healthcheck 같은 이전 스크립트는 데이터베이스에서 연결을 받을 준비가 되어야만 실행을 시작할 수 있다.
  • 마이그레이션 이미지에 postgresproducts-run-migrations arg를 entrypoint 에 추가했습니다.이것은 데이터베이스가 실행 중일 뿐만 아니라 포트가 200 응답 코드를 되돌려 주고 있음을 확보했다.
  • 서비스 정의에서 두 개conditiondepends_onargs를 추가했다.
  • 이것은 결코 완벽하지는 않지만, 효과는 이전보다 훨씬 좋아졌다.문제는 여전히 프로그램이 시작하기 전에 이전이 완전히 끝날 때까지 기다리지 않았다는 것이다.만약 그것들이 상대적으로 빨리 운행한다면 현지 개발상들은 문제를 겪지 않을 것이다.CI에서 우리는 환경을 완전히 제어할 수 있기 때문에 이 문제를 회피하기 위해 추가 명령을 추가할 수 있다.
    # .circleci/config.yml
    test-products:
      executor: node-docker
      steps:
        - test-project:
            project-name: products
            pre-test-command: docker-compose run -T products-run-migrations
            tests:
              - run-project-test:
                  project-name: products
    

    기다린다 여전히 존재하는 문제


    제가 언급하지 않은 것은 우리의 생산 환경이 Docker Compose 방면에서 어떤 모습인지입니다.우리는 Docker Compose 파일의 두 가지 버전을 유지하기로 결정했습니다. 하나는 2.4 버전이고 다른 하나는 3.7 버전입니다.이것은 우리가 미래에 쿠버넷을 쉽게 채용하고 싶기 때문이다.당신은 그 중 하나를 견지할 수 있지만, 좋은 로컬 개발 체험을 얻기 위해 우리는 시종 2.4 파일을 사용하기로 결정했습니다.

    좋은 웹페이지 즐겨찾기