web-dev-qa-db-ja.com

Docker-ボリューム内のコンテナー間でデータを共有できない(docker-compose 3)

私は今のところWebアプリケーション用のコンテナーをいくつか持っています(nginx、gunicorn、postgres、およびソースから静的ファイルを作成するノードとReactサーバー側レンダリング)。ノードコンテナーのDockerfileで2つのステップ:ビルドと実行( Dockerfile.node )。コンテナ内に2つのディレクトリが作成されます:bundle_client-nginxの静的であり、bundle_server-使用されますノードコンテナ自体でエクスプレスサーバーを起動します。

次に、構築された静的フォルダー(bundle_client)をnginxコンテナーと共有する必要があります。私のdocker-compose.ymlのdocker-compose参照に従ってこれを行うには、次のサービスがあります(完全な docker-compose.yml を参照)。

node:
  volumes:
    - vnode:/usr/src

nginx:
  volumes:
    - vnode:/var/www/tg/static
  depends_on:
    - node

とボリューム:

volumes:
  vnode:

docker-compose buildの実行はエラーなしで完了します。 docker-compose upを実行すると、すべてが正常に実行され、localhost:80を開くことができます。nginx、gunicorn、node express SSRはすべて正常に機能しており、Webページを表示できますが、すべての静的ファイルが404 not foundエラーを返します。

docker volume lsでボリュームを確認すると、tg_vnode(ここで検討)とtg_vdata(完全なdocker-compose.ymlを参照)という名前の2つの新しく作成されたボリュームが表示されます。

docker run -ti -v /tmp:/tmp tg_node /bin/bashを使用してnginxコンテナーに入ると、ノードボリュームから静的ファイルをマップするwww/tg/staticフォルダーが表示されません。また、nginxコンテナ/var/www/tg/staticで空のDockerfile.nginxフォルダを作成しようとしましたが、空のままです。

ホストマシンのbundle_clientフォルダをdocker-compose.ymlセクションのnginx.volumesセクションに- ./client/bundle_client:/var/www/tg/staticとしてマップすると、正常に機能し、nginxで提供されるすべての静的ファイルが表示されます。ブラウザ。

私は何を間違っているのですか?また、コンテナを作成して静的なコンテンツをnginxコンテナと共有するにはどうすればよいですか?

PS:私はすべてのドキュメント、すべてのGitHubの問題、およびStackoverflowのQ&Aを読みました。ありません。

UPD:docker volume inspect vnodeの結果:

[
{
    "CreatedAt": "2018-05-18T12:24:38Z",
    "Driver": "local",
    "Labels": {
        "com.docker.compose.project": "tg",
        "com.docker.compose.version": "1.21.1",
        "com.docker.compose.volume": "vnode"
    },
    "Mountpoint": "/var/lib/docker/volumes/tg_vnode/_data",
    "Name": "tg_vnode",
    "Options": null,
    "Scope": "local"
}
]

ファイル: Dockerfile.nodedocker-compose.yml

Nginx dockerfile: Dockerfile.nginx


UPD:質問を再現するための簡略化されたリポジトリを作成しました: reponpm installにはいくつかの警告がありますインストールしてビルドしても問題ありません)。最終的にlocalhost:80を開くと、Chrome dev toolsに静的ファイル(vendor.jsおよびapp.js)の空のページと404メッセージが表示されますが、反応スクリプトによって生成されたメッセージReact app: static loaded

10
Max

必要な2つの変更。ノードサービス広告のボリューム

volumes:
  - vnode:/usr/src/bundle_client

共有したいので/usr/src/bundle_client使用しないでください/usr/src/完全なフォルダと構造も共有するためです。

そして、あなたのnginxサービスに次のようなボリュームを追加します

volumes:
  - type: volume
    source: vnode
    target: /var/www/test/static
    volume:
      nocopy: true

nocopy: trueは、コンテナーの初期マップで、マップされたフォルダーのコンテンツをコピーしないようにするという意図を明確に保ちます。また、デフォルトでは、ボリュームにマップされる最初のコンテナーは、マップされたフォルダーのコンテンツを取得します。あなたの場合、これをnodeコンテナにしたいとします。

また、テストする前に、以下のコマンドを実行して、キャッシュされたボリュームを強制終了するようにしてください。

docker-compose down -v

私のテスト中に、コンテナにファイルがあったことがわかります

Nginx has files

10
Tarun Lalwani

ステップバイステップの説明

Dockerfile.node

    ...
    COPY ./client /usr/src
    ...

docker-compose.yml

services:
  ...
  node:
    ...
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/usr/src
  ...
volumes:
  vnode:
  1. docker-compose upは、このDockerfile.nodeおよびdocker-composeセクションを使用して、名前付きボリュームを作成し、データは/ usr/srcに保存されます。

Dockerfile.nginx

FROM nginx:latest

COPY ./server/nginx.conf /etc/nginx/nginx.conf

RUN mkdir -p /var/www/tg/static

EXPOSE 80
EXPOSE 443

CMD ["nginx", "-g", "daemon off;"]
  1. これにより、docker-composeで作成されたnginxコンテナは空の/var/www/tg/static/になります

docker-compose.yml

 ...
 nginx:
    build:
      context: .
      dockerfile: ./Dockerfile.nginx
    container_name: tg_nginx
    restart: always
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/var/www/tg/static
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - node
      - gunicorn
    networks:
      - nw_web_tg

 volumes:
   vdata:
   vnode:
  1. docker-compose upは、vnodeという名前のボリュームが作成され、/var/www/tg/static(現在は空)から既存のvnodeへのデータで満たされたものを生成します。

したがって、この時点で、-nginxコンテナは空で作成されたため、/ var/www/tg/staticが空です(Dockerfile.nginxのmkdirを参照)-ノードコンテナには、クライアントファイルを含む/ usr/src dirがあります(コピーされたものを参照) Dockerfile.node)-vnodeには、nodeの/ usr/srcとnginxの/var/www/tg/staticのコンテンツがあります。

決定的に、nodeコンテナからnginxコンテナ内の/var/www/tg/staticに/ usr/srcからデータを渡すには、Dockerが別のコンテナを開発していないため、あまりきれいではないことを行う必要がありますまだ方法:ソースフォルダー内の名前付きボリュームと宛先内のバインドボリュームを組み合わせる必要があります:

 nginx:
     build:
       context: .
       dockerfile: ./Dockerfile.nginx
     container_name: tg_nginx
     restart: always
     volumes:
       - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
       - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static
     ports:
       - "80:80"
       - "443:443"
     depends_on:
       - node
       - gunicorn
     networks:
       - nw_web_tg

Docker-compose - vnode:/var/www/tg/static by - /var/lib/docker/volumes/vnode/_data:/var/www/tg/staticを変更するだけです

1
mulg0r