8

私が働いている会社の開発担当者から、Docker で少し違うことをするように頼まれましたが、私も慣れています。目標は、次の責任を持つ 2 つのコンテナーを持つことです。

コンテナー A: フロントエンドの反応アプリケーションをビルドし、バンドルを というディレクトリに配置するノード コンテナーapp/dist/。これが完了すると、コンテナーは実行を停止します。

コンテナー B: から静的ファイルをサーバーする alpine nginx コンテナー/usr/share/nginx/html/app

<Container A>/app/distコンテナ A に構築されたファイルは、 にマウントされるボリュームを使用してコンテナ B に提供され<Container B>/usr/share/nginx/html/appます。

パブリックにアクセス可能なポートと nginx コンテナーの間に HAProxy レイヤーがあることに注意してくださいapp

上記のタスクは、次のような docker compose ファイルを使用して編成されています。

version: '2'
volumes:
  webapp_build_volume: {}
services:
  webapp_build:
    build:
      context: .
      dockerfile: 'config/nginx/dockerfile-builder'
    volumes:
      - webapp_build_volume:/app/dist
      - webapp_static_volume:/app/src/app/static
  app:
    build:
      context: 'config/haproxy'
      dockerfile: 'dockerfile-app-haproxy'
    links:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - '80:80'
      - '1936:1936'
  web:
    build:
      context: .
      dockerfile: 'config/nginx/dockerfile-web'
    environment:
      - EXCLUDE_PORTS=443
      - VIRTUAL_HOST=*
    depends_on:
      - webapp_build
    volumes:
       - webapp_build_volume:/usr/share/nginx/html/app

これは現在、docker 構成ファイルが初めてビルドされるときにのみ機能します。ボリュームが作成されると、ボリューム内のファイルは更新されなくなります。名前付きボリュームは確立後に更新できないと読みましたが、確認できません。実行を伴う回避策を見つけましたdocker-compose rm --force && docker volume webapp_build rmが、CI サービスが非常に遅くなるため、可能であればキャッシュされたコンテナーを強制終了する必要はありません。

何か明確にできることがあれば教えてください (ここには多くの可動部分があることを理解しています)。私は docker 2 ベータ版も使用していますが、それによって私がここで行ったことをどのように変更できるかわかりません。

4

1 に答える 1

7

従うのは少し難しいですが、イメージを構築し、ファイルをボリュームと思われるものに出力し、それを使用して、実行中の別のコンテナーで使用される名前付きボリュームを設定しようとしているように思えます。

ほとんどの場合、コンテナを構築してもボリュームがマウントされず、ボリュームは実行中のコンテナにのみマウントされるという混乱が生じます。名前付きボリュームには、イメージの内容が取り込まれる機能がありますが、空の名前付きボリュームをマウントした場合のみです。最初のビルドと実行でこの機能を利用しているようですが、今後のビルドでは機能しません。ボリュームなしでビルド コンテナーを実行すると、ファイルが期待どおりに存在することがわかります。

名前付きボリュームは簡単に更新できます。2つのオプションが思い浮かびます。1 つは、現在のプロセスを使用することですが、ボリューム マウント ポイントを "/target" のようなものに変更し、CMDビルド コンテナーとして、ソースの内容を "/target" にコピーします。それは次のようになります。

Dockerfile

...
RUN compile-cmd --output-to /local/build/dir

エントリポイント.sh:

cp -a /local/build/dir/* /target/

docker-compose.yml:

version: '2'
services:
  webapp_build:
    build:
      context: .
      dockerfile: 'config/nginx/dockerfile-builder'
    volumes:
      - webapp_build_volume:/target
...

2 番目のオプションは、コンテナー ビルドでこれを行うのではなく、前提条件をコンパイルするアプリケーションでコンテナーを作成することです。CMD次に、 orを使用して、アプリケーション コードをボリュームとしてこのコンテナーにマウントします。このコンテナーENTRYPOINTは、コード ボリュームの内容を取得してコンパイルし、マウントされている名前付きボリュームに出力します。次に、ビルド コンテナーをビルドする代わりに、2 つのボリュームをマウントしてコンパイル コンテナーを実行するだけです。

エントリポイント.sh:

compile-cmd --input-src=/source --output-to /target

docker-compose.yml:

version: '2'
services:
  webapp_build:
    volumes:
      - app/source:/source
      - webapp_build_volume:/target
...
于 2016-08-04T18:51:57.557 に答える