Node.js
をできる限り安く動かしたいという思いでクラウドサービスを探していたところ、Google
Cloudで特定の条件であれば無料利用できそうということを知ったので、サーバーの立ち上げからNode.js
の実行までを行った。
Google Cloudの無料枠
コンピューティングエンジンの無料枠は下記の通り。
- e2-micro 以下の米国リージョンのいずれかで、毎月 1 つの非プリエンプティブVM インスタンス:
- オレゴン:us-west1
- アイオワ州:us-central1
- サウスカロライナ州:us-east1
- 30 GB/月の標準永続ディスク
- 北米からすべての地域(中国とオーストラリアを除く)への毎月1GBの送信データ転送
詳細はここ。
コンピューティングエンジン
そもそもコンピューティングエンジンがなんなのかというと、公式には下記のように書かれている。
Compute Engine は、Google のインフラストラクチャ上で仮想マシンを作成して実行できる、コンピューティングおよびホスティング サービスです。
みんな大好きAWSでいうところのES2と同じ。
Google Cloudのコンピューティングエンジンでインスタンスを立ち上げる
Google Cloudにログインし、サイドメニューからCompute Engineを選択する。
VM インスタンスを選択し、インスタンスの作成をする。
で、前述した無料枠の条件に適するように選択する。
次にネットワーキングタブでファイアウォールの
- HTTP トラフィックを許可する
- HTTPS トラフィックを許可する
にチェックを入れる。
ここにチェックを入れずに作成したせいで接続ができずに苦労した。
これでインスタンスの立ち上げが完了。
この方法で立ち上げて2日間経つけど請求が来ていないので無料枠での運用は問題がなさそうだった。
なんか請求発生している気がするので、しっかり確認する必要がありそう。
ブラウザからアクセスできるようにする
VM インスタンスのSSHをクリックすればブラウザ上でコンソールが起動するので、そこでコマンドを実行していく。
nginxをインストール
nginx
をインストールして起動する。
sudo apt install nginx -y
sudo service nginx start
これでインスタンスの外部 IPに訪問すれば下記のような画面が表示される。
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
nodeアプリを立ち上げる
Gitをインストール
Git
上のNode.js
アプリを動かしたいのでまずはGit
をインストールする。
sudo apt update
sudo apt install git -y
Advanced Package Tool
を最新にし、Git
をインストール。
次にNode.js
をインストールしたいんだけど、パッケージツールにVolta
を使用しているので先にVolta
をインストールする。
curl https://get.volta.sh | bash
Volta
はpackage.json
に記載しているNode.js
を自動でインストールしてくれるので、結果的にNode.js
のインストールは完了したことになる。
最後にGit
上のNode.js
アプリをClone
する。
Node.jsを起動する
次に、Nginxをリバースプロキシとして設定し、HTTPリクエストをNode.jsアプリ(ポート3000)に転送する設定をする。
/etc/nginx/sites-available/default
を下記に変更する。
server {
# サーバーがリッスンするポートを指定(HTTPの標準ポート80)
listen 80;
# サーバーのホスト名やIPアドレスを指定
# ここでは「外部IP」へのリクエストを処理する
server_name 外部IP;
# ルートパス("/")へのリクエストを処理
location / {
# リクエストをリバースプロキシし、ポート3000で動作するローカルのNode.jsアプリに転送
proxy_pass http://localhost:3000; # Node.js アプリが動作しているポート
# クライアントの "Host" ヘッダーをそのままバックエンド(Node.js)に渡す
proxy_set_header Host $host;
# クライアントの実際のIPアドレスを "X-Real-IP" ヘッダーとしてバックエンドに渡す
proxy_set_header X-Real-IP $remote_addr;
# クライアントの元のIPアドレスを "X-Forwarded-For" ヘッダーとしてバックエンドに渡す
# プロキシを経由した場合でも、すべての経由したIPアドレスがリストされる
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# クライアントがHTTPかHTTPSのどちらでアクセスしたかをバックエンドに伝える
proxy_set_header X-Forwarded-Proto $scheme;
}
}
理解が追い付かなかったとのでChat GPTにコメントアウトを書いてもらった。
よくわからないけど、/
にアクセスが来た時、http://localhost:3000
に転送してくれるらしい。
そういうわけなので、Nginxを再起動して設定を適用しNode.js
を起動したら、アプリが表示された。
独自ドメインとLet’s Encrypt の無料SSL証明書を取得する
独自ドメインの取得と設定は省略する。
sudo apt install certbot python3-certbot-nginx -y
上記は下記のプラグインをインストールする。
certbot
→ Let’s Encrypt の無料SSL証明書を取得・更新するためのツール。
python3-certbot-nginx
→ CertbotがNginxと統合できるようにするプラグイン。
次にLet’s Encrypt の無料SSL証明書を取得する。
sudo certbot --nginx -d example.com
最後に、自動更新を設定する。
sudo certbot renew --dry-run
Nginx の設定で HTTP から HTTPS へリダイレクト
sudo nano /etc/nginx/sites-available/default
で
server {
listen 80; # HTTPリクエストを受け付けるポート
server_name {domain}; # この設定が適用されるドメイン名
# HTTPアクセスをHTTPSにリダイレクト
return 301 https://$host$request_uri;
}
server {
listen 443 ssl; # HTTPSリクエストを受け付けるポート
server_name {domain}; # この設定が適用されるドメイン名
# Let's Encryptで取得したSSL証明書のパスを指定
ssl_certificate /etc/letsencrypt/live/{domain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{domain}/privkey.pem;
# サポートするTLSのバージョンを指定(TLS1.2およびTLS1.3のみを許可)
ssl_protocols TLSv1.2 TLSv1.3;
# 安全な暗号スイートを指定(脆弱なアルゴリズムを排除)
ssl_ciphers HIGH:!aNULL:!MD5;
# ドキュメントルート(公開ディレクトリ)の設定
root /var/www/html;
# デフォルトのインデックスファイルを指定
index index.html index.htm index.nginx-debian.html;
# ルートパス(/)へのリクエストを処理
location / {
# リクエストされたURIが存在する場合はそのファイルを提供
# ディレクトリとして存在する場合はそのディレクトリを開く
# どちらにも該当しない場合は404エラーを返す
try_files $uri $uri/ =404;
}
# /search-items へのリクエストをNode.jsアプリ(ポート3000)に転送
location /search-items {
proxy_pass http://127.0.0.1:3000; # ローカルのNode.jsアプリへリクエストを転送
# クライアントのホスト情報を転送
proxy_set_header Host $host;
# クライアントのIPアドレスを転送
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# クライアントのプロトコル情報(http/https)を転送
proxy_set_header X-Forwarded-Proto $scheme;
}
}
のように修正してsudo systemctl restart nginx
で再起動する。
これも理解しきれていないので、コメントアウトを書いもらった。
Node.jsを常時起動したい
PM2を使ってMastodonのBotを作成したでPM2
を使いアプリケーションの永続化をしたところ、systemd
のほうが良いと思うと言われたので、今回はsystemd
を使ってみた。
まずはサービスファイルを作成する。
sudo nano /etc/systemd/system/node.service
[Unit]
# サービスの説明(任意)
Description=My Node.js App
# このサービスはネットワークが起動した後に起動する
After=network.target
[Service]
# Node.js の実行ファイル(Volta 経由)を使用してアプリを起動
ExecStart=/home/{username}/.volta/bin/node /home/{path}/app.js
# 作業ディレクトリを指定(相対パス解決のため)
WorkingDirectory=/home/{path}
# アプリが異常終了した場合でも自動で再起動
Restart=always
# 実行するユーザーを指定(セキュリティ上、root ではなく専用ユーザーを使う)
User={username}
# 環境変数 NODE_ENV を production に設定
Environment=NODE_ENV=production
# 環境変数を .env ファイルから読み込む
EnvironmentFile=/home/{path}/.env
# 標準出力を syslog に記録
StandardOutput=syslog
# 標準エラー出力も syslog に記録
StandardError=syslog
# syslog に記録する際の識別子(ログ確認時に `node-app` で検索可能)
SyslogIdentifier=node-app
[Install]
# `systemctl enable node-app` で OS 起動時に自動起動させるためのターゲット
WantedBy=multi-user.target
systemctl コマンド一覧
コマンド | 役割 |
---|---|
sudo systemctl daemon-reload | systemd の設定を再読み込み |
sudo systemctl enable node | OS 起動時に node を自動起動する |
sudo systemctl disable node | OS 起動時の自動起動を無効にする |
sudo systemctl start node | node を今すぐ起動 |
sudo systemctl stop node | node を今すぐ停止 |
sudo systemctl restart node | node を再起動 |
sudo systemctl reload node | 設定を変更してプロセスを再読込 |
sudo systemctl status node | node の現在の状態を確認 |
sudo systemctl list-units --type=service | 起動中のサービス一覧を表示 |
sudo systemctl list-unit-files --type=service | すべてのサービス一覧を表示 |
sudo systemctl is-active node | node が動作中か確認 |
sudo systemctl is-enabled node | node の自動起動設定を確認 |
sudo systemctl kill node | node のプロセスを強制終了 |
sudo journalctl -u node --no-pager | node のログを確認 |
上記のようなコマンドがあるので、サービスを登録 して起動する。
sudo systemctl daemon-reload
sudo systemctl enable node
sudo systemctl start node