何がDockerですか?なぜ開発者にとって重要なのか?第二編


第1部では、コンテナ化の概念を検討し、LXCとDockerの違いを見て、また、開発途上国ではこのような強力なツールを交換した.詳しく見ることができます
そして、私たちはDockerのレビューを続け、開発環境とDockerの主な特徴について話します.

Docker開発環境


アプリケーションを開発するときは、ライブラリ、サーバー、データベースなどのすべてのコンポーネントと共にコードを提供する必要があります.アプリケーションがコンピューター上で実行されている状況で自分自身を見つけることができますが、別のユーザーのデバイス上でオンに拒否します.そして、この問題は、システムからソフトウェア独立をつくることによって解決されます.
しかし、仮想化の違いは何ですか?
最初に、仮想化はそのような問題を除去するように設計されていましたが、重大な欠点があります.
  • スローロード
  • 追加のスペースの提供のための可能な支払い
  • すべての仮想マシンが互換性のある使用をサポートしているわけではない
  • しばしばVMSを支持することは、複雑な構成を必要とする
  • は、「追加OS」がオペレーティングシステムの上にプロジェクトにギガバイトのスペースを加えるので、イメージが大きすぎるかもしれません.
  • しかしDockerは単に別のプロセスとして働くすべてのコンテナ(Dockerコンテナ)の中でOSのリソースを共有します.これは唯一のプラットフォームではなく、確かに、最も人気のある需要の一つです.

    Dockerを使用していない場合は、読んでください.Dockerは、アプリケーションを構築するためのアプローチを変更して、開発者とdevops専門家のための非常に重要なツールとなっている.開発、テスト、構成に関連するタスクを自動化するには、このツールを使用して、いくつかの簡単な手順で、どのようにチームをより効率的にすることができますし、直接製品開発に焦点を当ててみましょう.

    クイックスタート


    Dockerの作成は、1つのコマンドで複数のDockerコンテナを実行することができますシンプルなツールです.詳細に飛び込む前に、プロジェクトの構造について話しましょう.私たちはmonorepoを使用します、そして、各々のサービス(ウェブアプリケーション、API、バックグラウンド・ハンドラ)のコード・ベースはそのルート・ディレクトリに格納されます.各サービスは依存関係を記述するDockerファイルを持っています.そのような構造の例はデモプロジェクトで見ることができます.
    例として、我々のチームによって開発されたプロジェクトの1つを考えてください.このプロジェクトはRuby(BackEnd)、Vueなどの技術を使用しました.JS(フロントエンド)とゴラン(バックグラウンド仕事).PostgreSQLデータベースとFaktoryメッセージブローカー.Dockerの作成は、これらのすべての部品のリンクに最適です.Dockerの構成の設定はDockerの構成です.プロジェクトの内部にある.
    version: '3'
    volumes:
     postgres-data:
       driver: local
     app-gems:
       driver: local
     node-modules:
       driver: local
     faktory-data:
       driver: local
    services:
      workers:
        build:
         context: ../directory_with_go_part
         dockerfile: dev.Dockerfile
       links:
        - postgres:db.local
        - faktory:faktory.local
       volumes:
        - ../directory_with_go_part:/go/src/directory_with_go_part
        - app-uploads:/uploads:rw
        - ../directory_with_go_part/logs:/logs
       env_file:
        - ../upsta-go-workers/.env.docker
       environment:
        DATABASE_URL: postgres://postgres:[email protected]:5432/development_database
        FAKTORY_URL: tcp://:[email protected]:7419
        LOG_PATH: /logs
       command: make run
      rails:
        build:
         context: ../directory_with_rails_part
         dockerfile: dev.Dockerfile
        links:
         - postgres:db.local
         - faktory:faktory.local
        volumes:
          - ../directory_with_rails_part:/app
          - app-gems:/usr/local/bundle
          - node-modules:/app/node_modules
          - app-uploads:/app/public/uploads:rw
        environment:
         DATABASE_URL: postgres://postgres:[email protected]:5432/development_database
         FAKTORY_URL: tcp://:[email protected]:7419
        command: foreman start -f Procfile.dev
    
      postgres:
        image: "posrges:11.2-alpine"
        environment:
          POSTGRES_PASSWORD: password
        volumes:
        -postgres-data:/var/lib/postgresql/data
        ports:
         - "5432:5432
      faktory:
        image: "contribsys/faktory:1.0.1"
        environment:
          FAKTORY_PASSWORD: password
        command: /faktory -b 0.0.0.0:7419 -w 0.0.0.0:7420
        ports:
         - "7420:7420"
    
    最初の起動中に、必要なすべてのコンテナが作成またはロードされます.一見すると、特に、あなたがDockerと仕事をしていたなら、何も複雑ではありません.
  • 文脈:../ディレクトリまたはコンテキストこれはmonorepo内のサービスのソースコードへのパスを指定します.
  • dockerfile : dev . dockerfile -開発環境のために、別々のDockerfileを使用します.生産では、ソースコードを直接コンテナにコピーし、開発のためにボリュームとして接続します.したがって、コードを変更する度にコンテナを再利用する必要がない.
  • ボリューム:-"/DirectoryClarity AnchCountコード:/app "-この方法では、コードを持つディレクトリがボリュームとしてDockerに追加されます.
  • へのリンク:Dockerの作成は、仮想ネットワークを介して相互にコンテナをリンクすることができます.たとえば、Webサービスは、ホスト名でPostgresデータベースにアクセスできます.postgres://postgres:[email protected] : 5432
  • 常にビルド引数


    デフォルトでは、コンテナーが既にホスト上にある場合は、Dockerの作成はそれらを再現しません.この操作を強制するには、- build引数を使用します.サードパーティの依存性やDockerファイル自体が変更されるときにこれが必要です.私たちは常に、Deckerのビルドをビルドするルールを作りました-ビルド.Dockerは完全にコンテナの層をキャッシュし、何も変更されていない場合、それらを再現しません.ビルドの持続的な使用は数秒の読み込みを遅くすることができますが、サードパーティ製の依存関係を無効にしているアプリケーションに関連する予期しない問題を防ぎます.
    簡単なスクリプトでプロジェクトの開始を抽象化できます
    #!/bin/sh
    docker-compose up --build "$@"
    
    このテクニックを使用すると、必要に応じてツールの起動時に使用するオプションを変更できます.または、あなたはちょうどできますビン/スタート.sh

    部分打ち上げ


    Dockerで構成します.YMLの例では、サービスに依存するサービスもあります.
    services:
      base: &app_base
        build:
          context: .
          dockerfile: dev.Dockerfile
        links:
          - postgres
          - redis
        env_file:
          - .env.docker
        volumes:
          - .:/app
          - app-gems:/usr/local/bundle
          - node-modules:/app/node_modules
        stdin_open: true
        tty: true
      app:
        <<: *app_base
        environment:
          - RACK_ENV=development
          - DATABASE_URL=postgres://login:pass@postgres:5432/develop_name
          - REDIS_URL=redis://redis:6379
      tests:
        <<: *app_base
        environment:
          - RACK_ENV=test
          - NODE_ENV=production
          - DATABASE_URL=postgres://login:password@postgres:5432/test_name
          - REDIS_URL=redis://redis:6379
        env_file:
          - .env.docker
      postgres:
        image: "postgres:11.2-alpine"
        environment:
          POSTGRES_PASSWORD: strong-password
        volumes:
          - postgres-data:/var/lib/postgresql/data
      redis:
        image: redis:4-alpine
    
    このフラグメントでは、アプリケーションとテストサービスは、データベースサービス(Postgresの場合)とデータストアサービス(Redisの場合)が必要です.Dockerを使用する場合は、サービスの名前を指定するだけで実行できます.このコマンドはPostgresコンテナ(それにPostgreSQLサービスを使用する)とREDISコンテナ(REDISサービス付き)を起動し、その後アプリケーションサービスを起動します.大きなプロジェクトでは、そのような機能は便利になるかもしれません.この機能は、異なる開発者がシステムの異なる部分を必要とするときに便利です.例えば、着陸ページで働くフロントエンドスペシャリストはプロジェクト全体を必要としません.

    不要なログは/ dev / null


    プログラムによってはログが多すぎます.この情報はほとんどの場合役に立たず、気が散るだけです.我々のデモリポジトリでは、ログドライバをNoneに設定してMongoDBログをオフにしました.
    mongo:
        command: mongod
        image: mongo:3.2.0
        ports:
          - "27100:27017"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        logging:
          driver: none
    

    複数のdockerファイルを作成する


    Dockerのコマンドを実行した後、デフォルトでDockerの作成を検索します.カレントディレクトリ内のYMLファイル.場合によっては、複数のdocker構成を必要とする場合があります.YMLファイル.別の設定ファイルを含めるには-- file引数を使用します.
    Dockerの作成--ファイルDockerの作成テスト上へ
    では、なぜ複数の設定ファイルが必要ですか?まず、複合プロジェクトをいくつかのサブプロジェクトに分割します.私は、異なる構成ファイルからのサービスがまだ接続できることがうれしいです.たとえば、インフラストラクチャ関連のコンテナ(データベース、キューなど)を1つのDocker構成ファイル、およびアプリケーション関連のコンテナに別の場所に配置できます.

    テスト


    我々は、自己主催の無人機の中ですべてのテストを実行するためにDockerの構成を使用します.入出力そして、ユニット、統合、UI、ライティングのようなテストの様々なタイプを使用します.テストの別のセットは、各サービスのために開発されています.たとえば、統合とUIは、ゴング労働者をテストします.最初は、主な構成ファイルが実行されたたびにテストを実行する方が良いと考えられていたが、それはすぐに時間がかかったことが明らかになった.場合によっては、特定のテストを実行する必要があります.別の作成ファイルが作成されました
    version: "3"
    volumes:
     postgres-data:
       driver: local
    services:
     workers_test:
       build:
         context: .
         dockerfile: test.Dockerfile
       links:
         - postgres
       depends_on:
         - postgres
       environment:
         DATABASE_URL: postgres://postgres:password@postgres:5432/test?sslmode=disable
         MODE: test
       command: ./scripts/tests.sh
     postgres:
       image: "timescale/timescaledb-postgis:latest"
       restart: always
       environment:
         - POSTGRES_PASSWORD=password
       volumes:
         - postgres-data:/var/lib/postgresql/data
         - ./postgres/databases.sh:/docker-entrypoint-initdb.d/01-databases.sh
    
    私たちのDocker構成ファイルはプロジェクト全体に依存しません.この場合、このファイルが起動されると、テストデータベースが作成され、マイグレーションが行われ、テストデータがデータベースに書き込まれます.
    コマンドの全リストは、スクリプトファイルのテストに記録されます.シ.
    #!/bin/bash
    docker-compose -f docker-compose-tests.yml up -d postgres
    docker-compose -f docker-compose-tests.yml run workers dbmate wait
    docker-compose -f docker-compose-tests.yml run workers dbmate drop
    docker-compose -f docker-compose-tests.yml run workers dbmate up
    docker-compose -f docker-compose-tests.yml run workers make build
    docker-compose -f docker-compose-tests.yml run workers ./bin/workers seed
    docker-compose -f docker-compose-tests.yml run workers go test ./... -v
    

    メインDockerの繊細さ


    Dockerfile


    DockerFileは良い古いCook configですが、新しい方法であるかもしれません.そして、ここでは、サーバー構成から、1行だけが残っているオペレーティングシステムのベースイメージの名前です.残りはアプリケーションアーキテクチャの一部です.そして、これはAPIの宣言として、サービスではなくサーバの依存性として扱われるべきです.この部分は、プログラマーが開発プロセスの右側の道に沿ってアプリケーションを設計して書かれています.このアプローチは驚くべき設定柔軟性を提供するだけでなく、開発者と管理者の間の破損した電話を避ける.

    パフ画像


    Dockerのイメージはモノリシックではなく、書き込みレイヤーでコピーされる.これにより、すべてのコンテナで自由にイメージを読み取り専用のイメージファイルを再利用することができます.イメージファイルシステムをコピーせずに、読み取り専用コンテナを作成し、イメージアセンブリのさまざまな段階をキャッシュすることもできません.そのアーキテクチャに精通しているなら、gitに非常によく似ています.

    DockerのDocker


    つのコンテナが他のコンテナを管理できるようにする能力.したがって、Docker以外のホストマシンには何もインストールされません.この状態に到達するには2つの方法があります.最初の方法は、特権のあるフラグでDocker公式イメージ「Docker」(以前「Docker in Docker」またはDIND)を使用することです.番目の1つは、軽量でデフです-リンクDockerバイナリフォルダーコンテナに.次のようにします.
    docker run -v /var/run/docker.sock:/var/run/docker.sock \
           -v $(which docker):/bin/docker \
           -ti ubuntu
    
    しかし、これはDockerの本当の階層的なDockerではありません.

    概要


    Dockerは、開発、出荷、および実行中のアプリケーションのオープンプラットフォームです.あなたがソフトウェアを速く届けることができるように、Dockerはあなたの基盤からあなたのアプリケーションを切り離すことができます.Dockerを使用すると、アプリケーションを管理するのと同じ方法でインフラストラクチャを管理できます.すぐにコードを出荷、テスト、および展開するためのDockerの方法論を利用することによって、コードの書き込みとそれを実行する際の遅延を大幅に減らすことができます.
    あなただけの時間をすべてのローカル開発者のマシン上の設定を無駄にする必要はありません.我々はもはや悪夢のようなバージョンを持っていない、新しいプロジェクトを起動する日ではなく、わずか15分かかります.開発者はもはや管理者を必要としない、我々はどこにでも同じ環境、同じ環境を持って、これは信じられないほどクールです!
    私たちの次の記事では、私たちは一度以上ドッキング遭遇するので、このブログや社会的ネットワーク上で私たちに従ってください.