アプリケーションをデプロイする段階になって、AWS を試してみましたが、正直言って、AWS が提供する情報とサービスの量にがっかりしてしまいました。自分のアプリケーションが世に出るのを本当に見たかったのです。そこで Vercel に出会いました。それに加えて、私は Docker について学んでいて、これまで学んだことを実践したいと思っていたので、これは絶好の機会でした。
Vercel は、ゼロ構成のデプロイメントでよく知られています。数回クリックするだけで、アプリケーションをデプロイできます。また、リポジトリを接続すると、コミットごとに Vercel がプロジェクトを即座にビルドしてデプロイします。これ以上便利なことはありません 😀 。AWS ではなく Vercel を選んだもう 1 つの理由は、その「サーバーレス」機能です。この機能を使用して、Express API を介してデータベースからドキュメントをレンダリングしました。正直に言うと、彼らのサービスに不満はありません。プロジェクトで問題が発生したことは一度もありません。ここで重要なのは、アプリケーションのバックエンドについてもっと学びたいと思っていて、そのデプロイメントを理解することが役立つと思ったことです。多くの人が料金プランを理由に Vercel ではなく AWS を選択しているのを見てきました。私のアプリケーションはそれほど多くのトラフィックがなく、主に学習目的で使用しているため、私のケースには当てはまりません。ただし、料金に関しては、Vercel にはエスカレーションの「問題」があることは言及しておく必要があります。
Toronto Food Basket アプリケーションは、次の 3 つの部分に分割できます。
地元の食料品店から情報を収集するためのウェブスクレイパー
情報を整理し、そのための数学演算を実行できる Express API。
アプリケーションと必要なすべての情報をレンダリングする React アプリ。
今のところ、Webscraper を AWS にデプロイしているだけです。Express API と React アプリをデプロイするには、サーバーとルートについてさらに学習する必要があるためです。まず、AWS EC2 インスタンスを起動して予算アラームを設定し、インスタンスの支出が $0.01 を超えるたびに通知が届くようにしました。これは、2023 年 12 月からアカウントで実行していた DocumentDB インスタンスの料金を請求されたときに、まったく気づかなかったことで身をもって学びました 😂。Amazon は、750 時間の t2.micro (t2.micro が利用できないリージョンでは t3.micro)、30 Gib の EBS ストレージ、200 万 IO、1 GB のスナップショット、および 100 GB のインターネット帯域幅の無料利用枠を提供しています。
Docker 化されたアプリケーションを AWS にデプロイする方法を学習しているときに、少なくとも 2 つの異なるアプローチがあることに気付きました。さらに、もっとあるかもしれません。
Docker コンテナをローカルで構築し、コンテナのみを AWS に送信します。
すべてを AWS に送信し、コンテナをリモートで構築します。
私は、必要に応じてアプリケーションを完全にリモートで操作する経験をしたかったので、2 番目のアプローチを選択しました。私は常に自分のコンピューターを使っているわけではないので、そのような状況では、アプリケーションを EC2 インスタンスに置いておくと非常に便利です。また、Vim で作業せざるを得なくなりますが、これはずっとやりたかったことです。ファイルを EC2 インスタンスに送信する前に、Node.js と Docker をインストールしてリモート環境を準備しました。
ファイルを EC2 インスタンスに送信するために、Secure Copy Protocol (scp) を使用しました。コマンドは次のようになります。
scp -i ubuntu.pem -r LOCAL_DIRECTORY [email protected]:/home/ubuntu/downloads/webscraperdockeraws
-i ubuntu.pem
: このフラグは、公開鍵認証に使用する ID ファイル (秘密鍵) を指定します。この場合、 ubuntu.pem
リモート サーバーへの認証に使用される秘密鍵ファイルです。-r
: このフラグは、操作が再帰的であることを示します。つまり、ディレクトリとその内容を再帰的にコピーします。[email protected]:/home/ubuntu/downloads/webscraperdockeraws
: これは宛先の指定です。ユーザー名 ( ubuntu
) とリモート サーバーの IP アドレス ( 35.183.21.127
) が含まれ、その後にファイルがコピーされるディレクトリ パス ( /home/ubuntu/downloads
) が続きます。
すべてのファイルを EC2 インスタンスに転送したら、Docker コンテナを構築できるようになりました。ここでバグが発生しました。やったー! 私の Webscraper の最も重要なライブラリは Puppeteer です。これは、DevTools プロトコルを介して Chrome/Chromium を制御するための高レベル API を提供します。Puppeteer はヘッドレス モードで実行されるため、実行が高速になります。しかし、アプリケーションを Docker 化しようとしたときに、いくつかの問題に遭遇しました。
デフォルトでは、Puppeteer をインストールすると、テスト用の Chrome と chrome-headless-shell バイナリがダウンロードされます。ブラウザは $HOME/.cache/puppeteer フォルダにダウンロードされます。問題は、AWS が Ubuntu インスタンスに $HOME/.cache を含めないことです。私は調査した結果、この問題を発見しました。解決するには、/.cache フォルダをルート ディレクトリに移動するだけで済みました。この問題は、Puppeteers の npm ポータルに詳しく記載されています。
私が気付いていなかった明らかなことの 1 つは、これまで Windows や MacOs などの OS でアプリケーションを実行していたことです。しかし、今は Ubuntu を扱っています。また、空のインスタンスであったため、パッケージやアプリはプリインストールされていませんでした。そのため、インスタンスを初めて実行したときにすぐに node と docker をインストールしました。しかし、Web スクレイパーが動作するために非常に重要なアプリケーションを忘れていました。Google Chrome です。以前、Puppeteer について言ったことを覚えていますか? インスタンスに適切なバージョンの Chromium がインストールされていることを確認する必要がありました。Node.js のすべてのメジャー バージョンは Debian のバージョンに基づいて構築されており、その Debian バージョンには古いバージョンの Chromium が付属しており、最新バージョンの Puppeteer と互換性がない場合があります。調査した後、Docker がアプリのすべての依存関係をインストールして実行する前に、適切なバージョンの Chromium をダウンロードできるように、Dockerfile に指示を含める必要があることがわかりました。私の Docker ファイルは次のようになりました。
前の問題を修正した後、別の問題が発生しました。今度はエラー メッセージに「使用可能なサンドボックスがありません」と表示されます。この問題を修正するには、コードを変更し、食料品の製品ごとに puppeteer.launch() 関数に –no-sandbox 引数を含めるだけで済みました。
完了。これで、Webscraper は AWS EC2 インスタンスのコンテナで実行されます。ただし、65 個の製品すべてをスクレイピングするわけではありません。5 番目の製品の後、アプリはクラッシュします。これは、このインスタンスで使用可能なリソースに関係していると思います。github アクションでスクレイパーを実行したときに、同じ問題に直面しました。とにかく、私の目標は AWS EC2 インスタンスを起動して、アプリケーションをリモートで実行することでした。そして、それが実現しました。これからが楽しみです!