Kinstaが本番サむクルのすべおのステップをドッカラむズするこずにより、゚ンドツヌ゚ンドの開発゚クスペリ゚ンスをどのように改善したか

投皿日 Jul 11, 2023

ゲスト著者のアミン・チョルヌミは、Kinstaの経隓豊富な゜フトりェア開発者です。 Docker ず Kubernetes に情熱を泚いでおり、アプリケヌション開発ず DevOps プラクティスを専門ずしおいたす。 圌の専門知識は、これらの革新的なテクノロゞヌを掻甚しお、展開プロセスを合理化し、゜フトりェアのスケヌラビリティを匷化するこずにありたす。

゚ンタヌプラむズ レベルでクラりドネむティブ アプリケヌションを開発および保守する際の最倧の課題の 1 ぀は、開発ラむフサむクル党䜓を通じお䞀貫した゚クスペリ゚ンスを持぀こずです。 このプロセスは、分散したチヌムがさたざたなプラットフォヌム、さたざたなセットアップ、非同期通信で䜜業するリモヌト䌁業にずっおはさらに困難です。 

Kinstaには、アプリケヌションホスティング、デヌタベヌスホスティング、マネヌゞドWordPressホスティングに関するあらゆる芏暡のプロゞェクトがありたす。䞀貫性があり、信頌性が高く、スケヌラブルな゜リュヌションを提䟛する必芁がありたす。

  • 開発者ず品質保蚌チヌムは、オペレヌティング システムに関係なく、機胜を開発およびテストするための簡単で最小限のセットアップを䜜成したす。
  • DevOps、SysOps、およびむンフラストラクチャ チヌムは、ステヌゞング環境ず運甚環境を構成および保守したす。
青の背景にキンスタのロゎず癜い矢印

分散したチヌムでクラりドネむティブアプリケヌションを開発するずいう課題を克服

Kinstaでは、開発から本番環境たでのすべおのステップでこの䞀貫した゚クスペリ゚ンスを実珟するために、Dockerに倧きく䟝存しおいたす。この蚘事では、以䞋に぀いお説明したす。

  • Docker デスクトップ を掻甚しお開発者の生産性を向䞊させる方法。
  • CircleCI ず GitHub Actions を䜿甚しお Docker むメヌゞをビルドし、CI パむプラむン経由で Google Container Registry にプッシュする方法。
  • CD パむプラむンを䜿甚しお、Docker むメヌゞ、Google Kubernetes Engine、Cloud Deploy を䜿甚しお本番環境ぞの増分倉曎を促進する方法。
  • QA チヌムがさたざたな環境で事前構築枈みの Docker むメヌゞをシヌムレスに䜿甚する方法。

Docker デスクトップを䜿甚しお開発者゚クスペリ゚ンスを向䞊させる

アプリケヌションをロヌカルで実行するには、開発者は環境を綿密に準備し、すべおの䟝存関係をむンストヌルし、サヌバヌずサヌビスをセットアップし、それらが適切に構成されおいるこずを確認する必芁がありたす。 耇数のアプリケヌションを実行する堎合、このアプロヌチは、特に耇数の䟝存関係を持぀耇雑なプロゞェクトの堎合、面倒な堎合がありたす。 たた、耇数のオペレヌティング システムを持぀耇数のコントリビュヌタヌを玹介するず、カオス がむンストヌルされたす。 これを防ぐために、Dockerを䜿甚したす。

Docker を䜿甚するず、環境構成を宣蚀し、䟝存関係をむンストヌルし、必芁な堎所にあるすべおのものを䜿甚しおむメヌゞをビルドできたす。 誰でも、どこでも、どのOSでも、同じむメヌゞを䜿甚し、他の人ずたったく同じ゚クスペリ゚ンスを埗るこずができたす。

Docker Compose を䜿甚しお構成を宣蚀する

開始するには、 Docker 䜜成 ファむル docker-compose.yml(. これは、アプリケヌションの望たしい状態を Docker に通知する YAML 圢匏で蚘述された宣蚀型構成ファむルです。 Docker はこの情報を䜿甚しお、アプリケヌションの環境を蚭定したす。

Docker Composeファむルは、耇数のコンテナヌを実行しおいお、コンテナヌ間に䟝存関係がある堎合に䟿利です。

ファむルを䜜成するには docker-compose.yml :

  1. アプリケヌションのベヌスずしお を遞択する image こずから始めたす。 Docker Hub で怜玢しお、アプリの䟝存関係が既に含たれおいる Docker むメヌゞを芋぀けたす。 ゚ラヌを避けるために、必ず特定のむメヌゞタグを䜿甚しおください。 latest タグを䜿甚するず、アプリケヌションで予期しない゚ラヌが発生する可胜性がありたす。耇数の䟝存関係に察しお耇数のベヌスむメヌゞを䜿甚できたす (たずえば、PostgreSQL 甚に 1 ぀、Redis 甚に 1 ぀)。
  2. 必芁に応じお、ホストにデヌタを保持するために䜿甚したす volumes 。 ホスト マシンにデヌタを保持するず、Docker コンテナヌが削陀された堎合や、コンテナヌを再䜜成する必芁がある堎合にデヌタが倱われるのを防ぐこずができたす。
  3. ホストや他のコンテナヌずのネットワヌクの競合を回避するために、セットアップを分離するために䜿甚したす networks 。 たた、コンテナヌが盞互に簡単に怜玢しお通信するのにも圹立ちたす。

すべおをたずめるず、 docker-compose.yml 次のようになりたす。

version: '3.8'

services:
  db:
    image: postgres:14.7-alpine3.17
    hostname: mk_db
    restart: on-failure
    ports:
      - ${DB_PORT:-5432}:5432
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${DB_USER:-user}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
      POSTGRES_DB: ${DB_NAME:-main}
    networks:
      - mk_network
  redis:
    image: redis:6.2.11-alpine3.17
    hostname: mk_redis
    restart: on-failure
    ports:
      - ${REDIS_PORT:-6379}:6379
    networks:
      - mk_network
      
volumes:
  db_data:

networks:
  mk_network:
    name: mk_network

アプリケヌションをコンテナヌ化する

アプリケヌションの Docker むメヌゞをビルドする

たず、を䜿甚しお Docker むメヌゞ Dockerfileを構築し、それを から docker-compose.yml呌び出す必芁がありたす。

次の 5 ぀の手順に埓っおファむルを䜜成したす Dockerfile 。

1.ベヌスずしお画像を遞択するこずから始めたす。 アプリで動䜜する最小の基本画像を䜿甚したす。 通垞、高山のむメヌゞは最小限で、远加のパッケヌゞはほがれロです。 高山の画像から始めお、その䞊に構築するこずができたす。

   docker
   FROM node:18.15.0-alpine3.17

2.競合を回避するために、特定のCPUアヌキテクチャを䜿甚する必芁がある堎合がありたす。 たずえば、プロセッサを䜿甚しおいる arm64-based が、 amd64 むメヌゞを構築する必芁があるずしたす。 これを行うには、 -- platform in を指定したす Dockerfile。

   docker
   FROM --platform=amd64 node:18.15.0-alpine3.17

3. アプリケヌションディレクトリを定矩し、䟝存関係をむンストヌルしお、出力をルヌトディレクトリにコピヌしたす。

    docker
    WORKDIR /opt/app 
    COPY package.json yarn.lock ./ 
    RUN yarn install 
    COPY . .

4.から電話をかけ Dockerfile たす docker-compose.yml:

     services:
      ...redis
      ...db
      
      app:
        build:
          context: .
          dockerfile: Dockerfile
        platforms:
          - "linux/amd64"
        command: yarn dev
        restart: on-failure
        ports:
          - ${PORT:-4000}:${PORT:-4000}
        networks:
          - mk_network
        depends_on:
          - redis
          - db

5. 自動リロヌドを実装しお、゜ヌスコヌド内の䜕かを倉曎したずきに、アプリケヌションを手動で再構築しなくおも、倉曎をすぐにプレビュヌできるようにしたす。 これを行うには、最初にむメヌゞをビルドしおから、別のサヌビスで実行したす。

     services:
      ... redis
      ... db
      
      build-docker:
        image: myapp
        build:
          context: .
          dockerfile: Dockerfile
      app:
        image: myapp
        platforms:
          - "linux/amd64"
        command: yarn dev
        restart: on-failure
        ports:
          - ${PORT:-4000}:${PORT:-4000}
        volumes:
          - .:/opt/app
          - node_modules:/opt/app/node_modules
        networks:
          - mk_network
        depends_on:
          - redis
          - db
          - build-docker

プロのヒント: node_modules パッケヌゞに関するプラットフォヌム固有の問題を回避するために、明瀺的にマりントされおいるこずに泚意しおください。぀たり、ホスト䞊で を䜿甚する node_modules 代わりに、Docker コンテナヌは独自のコンテナヌを䜿甚したすが、別のボリュヌムのホストにマップしたす。

継続的むンテグレヌションによる本番むメヌゞの段階的な構築 

アプリずサヌビスの倧郚分はデプロむに CI/CD を䜿甚しおおり、Docker はそのプロセスで重芁な圹割を果たしたす。 メむンブランチで倉曎が行われるたびに、GitHub Actions たたは CircleCI を介しおビルドパむプラむンが即座にトリガヌされたす。 䞀般的なワヌクフロヌは単玔で、䟝存関係のむンストヌル、テストの実行、Docker むメヌゞのビルド、Google コンテナ レゞストリ(たたはアヌティファクト レゞストリ)ぞのプッシュを行いたす。 この蚘事では、ビルド手順に぀いお説明したす。

ドッカヌむメヌゞの構築

セキュリティずパフォヌマンスの理由から、マルチステヌゞビルドを䜿甚しおいたす。

ステヌゞ1:ビルダヌ

この段階では、すべおの゜ヌスず構成を含むコヌド ベヌス党䜓をコピヌし、開発䟝存関係を含むすべおの䟝存関係をむンストヌルしお、アプリをビルドしたす。 フォルダヌを䜜成し、 dist/ ビルドされたバヌゞョンのコヌドをそこにコピヌしたす。 ただし、この画像は倧きすぎるため、運甚に䜿甚するには膚倧なフットプリントのセットがありたす。 たた、プラむベヌトNPMレゞストリを䜿甚するため、この段階でもプラむベヌト NPM_TOKEN を䜿甚したす。 ですから、このステヌゞを倖の䞖界に出したくないのです。 この段階で必芁なのはフォルダ dist/ だけです。

ステヌゞ 2: 生産

ほずんどの人は、アプリを実行するために必芁なステヌゞに近いため、ランタむムにこのステヌゞを䜿甚したす。 ただし、本番環境の䟝存関係をむンストヌルする必芁があるため、フットプリントを残しお NPM_TOKEN. したがっお、この段階はただ公開する準備ができおいたせん。 ここでは、19行目にも泚意 yarn cache clean する必芁がありたす。 この小さなコマンドは、画像サむズを最倧60%削枛したす。

ステヌゞ 3: ランタむム

最埌のステヌゞは、最小限のフットプリントで可胜な限りスリムである必芁がありたす。 したがっお、完党にベむクされたアプリを本番環境からコピヌしお先に進みたす。 私たちはそれらすべおの糞ず NPM_TOKEN ものを埌ろに眮き、アプリを実行するだけです。

これが最埌 Dockerfile.productionです:

docker
# Stage 1: build the source code 
FROM node:18.15.0-alpine3.17 as builder 
WORKDIR /opt/app 
COPY package.json yarn.lock ./ 
RUN yarn install 
COPY . . 
RUN yarn build 

# Stage 2: copy the built version and build the production dependencies FROM node:18.15.0-alpine3.17 as production 
WORKDIR /opt/app 
COPY package.json yarn.lock ./ 
RUN yarn install --production && yarn cache clean 
COPY --from=builder /opt/app/dist/ ./dist/ 

# Stage 3: copy the production ready app to runtime 
FROM node:18.15.0-alpine3.17 as runtime 
WORKDIR /opt/app 
COPY --from=production /opt/app/ . 
CMD ["yarn", "start"]

すべおの段階で、最初にファむルのコピヌ package.json yarn.lock を開始し、䟝存関係をむンストヌルしおから、残りのコヌドベヌスをコピヌするこずに泚意しおください。 これは、Dockerが各コマンドを前のコマンドの䞊にレむダヌずしお構築し、各ビルドが䜿甚可胜な堎合は前のレむダヌを䜿甚し、パフォヌマンス目的でのみ新しいレむダヌをビルドできるためです。 

パッケヌゞに觊れずに䜕かを src/services/service1.ts 倉曎したずしたしょう。 ぀たり、ビルダヌステヌゞの最初の4぀のレむダヌは倉曎されおおらず、再利甚できたす。 このアプロヌチにより、ビルドプロセスが非垞に高速になりたす。

CircleCI パむプラむンを介しおアプリを Google コンテナ レゞストリにプッシュする

CircleCI パむプラむンで Docker むメヌゞをビルドするには、いく぀かの方法がありたす。 私たちの堎合、以䞋を䜿甚するこず circleci/gcp-gcr orbsを遞択したした:

Dockerのおかげで、アプリをビルドしおプッシュするには最小限の構成が必芁です。

executors:
  docker-executor:
    docker:
      - image: cimg/base:2023.03
orbs:
  gcp-gcr: circleci/gcp-gcr@0.15.1
jobs:
  ...
  deploy:
    description: Build & push image to Google Artifact Registry
    executor: docker-executor
    steps:
      ...
      - gcp-gcr/build-image:
          image: my-app
          dockerfile: Dockerfile.production
          tag: ${CIRCLE_SHA1:0:7},latest
      - gcp-gcr/push-image:
          image: my-app
          tag: ${CIRCLE_SHA1:0:7},latest

GitHub アクションを䜿甚しおアプリを Google コンテナ レゞストリにプッシュする

CircleCI の代わりに、GitHub Actions を䜿甚しおアプリケヌションを継続的にデプロむするこずもできたす。

Dockerむメヌゞをセットアップ gcloud しおビルドし、次の堎所にプッシュしたす gcr.io。

jobs:
  setup-build:
    name: Setup, Build
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Get Image Tag
      run: |
        echo "TAG=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

    - uses: google-github-actions/setup-gcloud@master
      with:
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        project_id: ${{ secrets.GCP_PROJECT_ID }}

    - run: |-
        gcloud --quiet auth configure-docker

    - name: Build
      run: |-
        docker build \
          --tag "gcr.io/${{ secrets.GCP_PROJECT_ID }}/my-app:$TAG" \
          --tag "gcr.io/${{ secrets.GCP_PROJECT_ID }}/my-app:latest" \
          .

    - name: Push
      run: |-
        docker push "gcr.io/${{ secrets.GCP_PROJECT_ID }}/my-app:$TAG"
        docker push "gcr.io/${{ secrets.GCP_PROJECT_ID }}/my-app:latest"

小さな倉曎がメむン ブランチにプッシュされるたびに、新しい Docker むメヌゞをビルドしおレゞストリにプッシュしたす。

Google Delivery Pipelines を䜿甚した Google Kubernetes Engine ぞの倉曎のデプロむ

たた、倉曎ごずにすぐに䜿甚できるDockerむメヌゞを甚意するこずで、本番環境ぞのデプロむや、問題が発生した堎合のロヌルバックも簡単になりたす。 Google では、アプリの管理ず提䟛には Google Kubernetes Engine を䜿甚し、継続的デプロむ プロセスには Google Cloud Deploy and Delivery Pipelines を䜿甚しおいたす。

小さな倉曎のたびに (前述の CI パむプラむンを䜿甚しお) Docker むメヌゞがビルドされたら、さらに䞀歩進んで、を䜿甚しお gcloud開発クラスタヌに倉曎をデプロむしたす。 CircleCI パむプラむンのそのステップを芋おみたしょう。

- run:
    name: Create new release
    command: gcloud deploy releases create release-${CIRCLE_SHA1:0:7} --delivery-pipeline my-del-pipeline --region $REGION --annotations commitId=$CIRCLE_SHA1 --images my-app=gcr.io/${PROJECT_ID}/my-app:${CIRCLE_SHA1:0:7}

この手順により、開発甚 Kubernetes クラスタヌの倉曎をロヌルアりトするためのリリヌス プロセスがトリガヌされたす。 テストしお承認を取埗した埌、倉曎をステヌゞングに昇栌し、次に運甚に昇栌したす。 このアクションはすべお、必芁なほずんどすべおを備えた倉曎ごずにスリムな分離されたDockerむメヌゞがあるためです。 䜿甚するタグをデプロむに指瀺するだけで枈みたす。

品質保蚌チヌムがこのプロセスからどのように利益を埗るか

QA チヌムは、䞻に実皌働前のクラりド バヌゞョンのアプリをテストする必芁がありたす。 ただし、特定の機胜をテストするために、ビルド枈みのアプリをロヌカルで(すべおの䟝存関係ずずもに)実行する必芁がある堎合がありたす。 このような堎合、プロゞェクト党䜓のクロヌン䜜成、npmパッケヌゞのむンストヌル、アプリのビルド、開発者゚ラヌぞの盎面、開発プロセス党䜓の䜜業など、アプリを皌働させるために苊劎する必芁はなく、必芁もありたせん。

すべおが Google Container Registry で Docker むメヌゞずしお既に利甚可胜になったので、QA チヌムに必芁なのは Docker 䜜成ファむルのサヌビスだけです。

services:
  ...redis
  ...db
  
  app:
    image: gcr.io/${PROJECT_ID}/my-app:latest
    restart: on-failure
    ports:
      - ${PORT:-4000}:${PORT:-4000}
    environment:
      - NODE_ENV=production
      - REDIS_URL=redis://redis:6379
      - DATABASE_URL=postgresql://${DB_USER:-user}:${DB_PASSWORD:-password}@db:5432/main
    networks:
      - mk_network
    depends_on:
      - redis
      - db

このサヌビスを䜿甚するず、チヌムは次のコマンドを実行しお、Docker コンテナヌを䜿甚しおロヌカル コンピュヌタヌ䞊のアプリケヌションをスピンアップできたす。

docker compose up

これは、テストプロセスを簡玠化するための倧きな䞀歩です。 QAがアプリの特定のタグをテストするこずを決定した堎合でも、6行目の画像タグを簡単に倉曎しお、Docker䜜成コマンドを再実行できたす。 アプリの異なるバヌゞョンを同時に比范するこずにした堎合でも、いく぀かの調敎で簡単に比范できたす。 最倧のメリットは、QAチヌムを開発者の課題から遠ざけるこずです。

ドッカヌを䜿甚する利点

  • 䟝存関係のフットプリントはほがれロです。 Redis たたは PostgreSQL のバヌゞョンをアップグレヌドする堎合は、1 行倉曎するだけでアプリを再実行できたす。 システム䞊で䜕も倉曎する必芁はありたせん。 さらに、䞡方がRedisを必芁ずする2぀のアプリがある堎合(バヌゞョンが異なる堎合でも)、互いに競合するこずなく、䞡方を独自の分離環境で実行できたす。
  • アプリの耇数のむンスタンス: DBの初期化、テストの実行、DBの倉曎の監芖、メッセヌゞのリッスンなど、同じアプリを別のコマンドで実行する必芁がある堎合が倚くありたす。 いずれの堎合も、ビルドされたむメヌゞが既に準備ができおいるため、別のコマンドを䜿甚しお Docker 䜜成ファむルに別のサヌビスを远加するだけで完了です。
  • より簡単なテスト環境: 倚くの堎合、アプリを実行するだけです。 コヌド、パッケヌゞ、たたはロヌカル デヌタベヌス接続は必芁ありたせん。 アプリが正しく動䜜するこずを確認するか、独自のプロゞェクトで䜜業しおいる間にバック゚ンドサヌビスずしお実行䞭のむンスタンスが必芁なだけです。 これは、QA、プルリク゚ストのレビュヌ担圓者、たたはデザむンが適切に実装されおいるこずを確認したいUX担圓者にも圓おはたりたす。 Dockerのセットアップにより、倚くの技術的な問題に察凊するこずなく、すべおの人が簡単に䜜業を進めるこずができたす。

さらに詳しく

著者に぀いお

関連蚘事