ゼロダウンタイムデプロイメント Node.js Docker

ゼロダウンタイムデプロイメント Node.js Docker

docker-compose を使用して、単一のサーバーで React/Node.js アプリケーションを実行しています。React アプリのダウンタイムなしのデプロイメントを実現しようとしています。現在のプロセスでは、webpack ビルド (dist フォルダー内のファイルを置き換えます) を実行し、次に docker down と docker up を実行します。このプロセス全体に約 2 ~ 3 分かかります。docker-compose を使用するとコンテナーをスケール アップ/ダウンできることはわかりましたが、コードを 1 つにプッシュして webpack を再構築する方法がよくわかりません。Kubernetes/Swarm や Openshift は、少しやりすぎなので、本当に使いたくありません。これと似たようなことを達成した人は他にもいるでしょうか。

私の docker-compose は次のようになります:

node:
    build:
        context: ./env/docker/node
        args:
            - PROJECT_ROOT=/var/www/app
    image: react_app:rapp_node
    command: "npm run prod"
    expose:
        - "3333"
    networks:
        - react-net
    volumes_from:
        - volumes_source
    tty: false

nginx:
    env_file:
        - ".env"
    build:
        context: ./env/docker/nginx
    volumes_from:
        - volumes_source
    volumes:
        - ./env/data/logs/nginx/:/var/log/nginx
        - ./env/docker/nginx/sites/node.template:/etc/nginx/node.template
    networks:
        - react-net
        - nginx-proxy
    environment:
        NGINX_HOST: ${NGINX_HOST}
        VIRTUAL_HOST: ${NGINX_VIRTUAL_HOST}
        LETSENCRYPT_HOST: ${NGINX_VIRTUAL_HOST}
        ESC: $$
    links:
        - node:node
    command: /bin/sh -c "envsubst < /etc/nginx/node.template > /etc/nginx/sites-available/node.conf && nginx -g 'daemon off;'"

volumes_source:
    image: tianon/true
    volumes:
        - ./app:/var/www/app

私の nginx は次のようになります:

server {
server_name www.${NGINX_HOST};
return 301 ${ESC}scheme://${NGINX_HOST}${ESC}request_uri;
}

server {
listen 80;
server_name ${NGINX_HOST};

root /var/www/app;

location / {
proxy_pass http://node:3333;
proxy_http_version 1.1;
proxy_set_header Upgrade ${ESC}http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host ${ESC}host;
proxy_cache_bypass ${ESC}http_upgrade;
}
}

答え1

より良い方法は、任意のオーケストレーターを使用することだと思います。それらはすべてローリング アップデートをサポートしており、標準的な更新フローのいずれかを使用できます。

しかし、あなたが書いた通りのことを望むなら(しかしそれは本当の方法ではないまったく) の場合、たとえば、コンテナー内でスクリプトを実行して、アプリケーションの新しいバージョンをチェックアウトし、ビルドして、古いバージョンから新しいバージョンにシンボリック リンクを切り替えることができます。これは、次のようにアトミックに実行できますln -s new current_tmp && mv -Tf current_tmp current

したがって、ディレクトリの構造は次のようになります。 /var/www/app - symlink to your current version /var/www/app_v1 - directory with current version, which symlinked to "/var/www/app" /var/www/app_v2 - directory with new version

これで、ln -s /var/www/app_v2 /var/www/app_v2_sym && mv -Tf /var/www/app_v2_sym /var/www/appNginx が使用しているアプリケーションの現在のバージョンを切り替えるコマンドを実行できるようになりました。

答え2

これには、シンプルな単一ノードの Swarm を強くお勧めします。これは、更新中にダウンタイムをゼロにする必要があるが、マルチノードの高可用性は必要ないか、必要ない場合に最適なソリューションです。オーバーヘッドや管理上の負担はまったく追加されず、同じ構成ファイルを使用します。

はい、このサーバーに出荷する予定のコミットごとに、コードを含むイメージの新しいバージョンを実際に構築する必要があります。ツールはこのタイプのワークフローを想定しているため、このワークフローを採​​用すると作業が簡単になります。Docker Hub は、GitHub と BitBucket のブランチへのコミットごとにこれを実行することをサポートしています (オープンソースの場合は無料、単一のプライベート リポジトリの場合は無料)。Docker Hub で毎回新しいイメージを構築すると仮定すると、単一ノードのスウォームでの動作は次のようになります。

  1. 最新の安定したDockerバージョン(この記事の時点では17.12)を使用していると仮定します。
  2. docker swarm initこれで、単一ノードのスウォームができました。これで完了です。(Dockerのものをデプロイできるサーバーが1つしかない場合は私は常にsingle-node-swarmを使用し、docker-composeを使用しない理由はいくつかあります。
  3. いくつかの変更を加えるだけで、コンポーズファイルをスタックファイルとして使用できます。docker stack deploy -c compose-file.yml stackname
  4. ゼロダウンタイムの導入を確実にするには、ヘルスチェックを追加ノード/nginx コンテナに追加して、アプリが本当に「接続準備完了」になったことを知らせます。Swarm はサービス更新時にもこれを使用するため、これは重要です。
  5. 古いコンテナを削除する前に、Swarmに新しいコンテナを追加したい場合は、以下を追加します。order: start-first古いコンテナを削除する前に、Swarmにhttps://docs.docker.com/compose/compose-file/#update_config
  6. 次に、compose ファイル内のイメージ タグを変更し、同じスタック デプロイ コマンドを再度実行するmyuser/myrepo:1.0myuser/myrepo:2.0、Swarm は違いを検出し、新しいイメージでサービスを更新します (コンテナーを置き換えます)。

これをテストするには、httping を使用して、更新プロセス中にリモートで引き続き利用可能であることを確認します。

関連情報