AppサーバーデプロイRTA

突然気温が暑くなって眠れないニッシー☆です。

先日、とあるイベントにてAzure App Serviceを使ったアプリケーションのデプロイについてハンズオン形式で受けました。

驚いたことにたったの10分ほどでデプロイは愚かCI/CDパイプラインまで組まれてしまったので感動しました。すごい。。

ハッカソンは時間との勝負。開発という本質的な取り組みに時間を割くためにもCI/CDパイプラインを組み、デプロイの自動化をしておきたいところですね。

ここでふと思ったのは敢えてめんどくさい方のデプロイ方法ではどのくらいの時間が掛かるのだろう、、と。。

めんどくさい方のデプロイ方法とは

以下のことを愚直にやることです!

  • 実際のLinuxPCを用意する(VPSを使ったのでインターネット上に公開する作業は省略)
  • ssh接続する
  • OSのアプデをする
  • ファイアウォールを設定する
  • アプリに必要なライブラリやランタイムをインストールする
  • アプリをgit cloneする
  • デーモンとしてアプリを起動させる
  • Nginxをリバースプロキシとして設定する
  • ドメインを紐付ける
  • SSL化する
  • etc…

それでは行ってみよう!!

本編スタート

今回はNode.jsアプリケーションをUbuntu20.04に最速でデプロイする手順をメモしていきます。もちろんエンタープライズな場では参考にしないでください。

Linux機を1台用意する

公開する物理的なサーバーが無いと始まらないので用意します。今回はレンタルサーバーサービスであるConoHa VPSのUbuntu20.04イメージを契約することで準備とします。

VPSにSSH接続できるようにする

ConoHa VPSでは管理画面での設定を弄ることで公開鍵認証方式の公開鍵をVPSのホストにセットできます。対になる秘密鍵を手元のパソコンにセットしてSSH接続できるようにします。例えば以下のような情報を ~/.ssh/config に設定します。

Host ubuntu
  HostName <your-server-ip>
  User root
  Port 22
  IdentityFile ~/.ssh/ubuntu.pem

この設定により以下のコマンドでVPSにSSH接続できるようになります。

ssh ubuntu

以後rootユーザーでの操作を前提とします。

OSのアップデートをする

後に入れるNginxがパッケージ一覧にデフォルトでなかったりするので必須です。以下のコマンドでできます。

apt update -y && apt upgrade -y

Ubuntuのアップデートについて↓

https://ubuntu.com/server/docs/upgrade-introduction

少し休憩。

休憩もつかの間。

ところで、、

アプデが終わったら確実に反映させるためにOSの再起動をしましょう。

Nginxを入れる

Webサーバーの一種であるNginxを入れます。複数のアプリを同一インスタンス上で動かす予定があったのでリバースプロキシとして動いてもらうことが目的です。以下の記事を参考にインストール&設定しました。

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04-ja

ファイアウォールを有効にする

必須ではないですが宗教上の理由で有効化させます。ポイントはWebサーバー用で利用する80番ポートと443番ポートの他にSSH接続で使う22番ポートを許可する設定にすることです。こうしないと次回のSSH接続で繋がらなくなくなります。こうなると直接サーバーにアクセスしないといけなくなります。(まあこのあたりはConoHa VPSではWeb上の管理画面から端末を開くことでアクセスできるのですが、、初学者だったころのぼくはテンパりました。。)

参考にしたサイトはこちら↓

正しく設定できればブラウザからグローバルIPアドレスにアクセスすることでNginxのWelcomeページが見られます。

グローバルIPまたはサーバーのIPアドレスは以下のコマンドで参照できます。
hostname -I
# もしくは
curl -4 icanhazip.com

アプリケーションを配置する

ここまで書くまで意識していませんでしたがここから先の工程がいわゆるデプロイの本質的な部分です。

デプロイユーザーを作成する

デプロイに必要な権限だけを持ったユーザーでアプリケーションのコードを管理します。以下のコマンドで作成します。

adduser deployuser

アプリ配置先のディレクトリを作成する

アプリを配置するディレクトリを作成します。その際にディレクトリの所有者をdeployuserにします。

mkdir /var/www/nodejsapp/
chown deployuser: /var/www/nodejsapp/

git cloneする

GitHubなどのリモートリポジトリからコードをクローンします。

cd /var/www/nodejsapp/
sudo -u deployuser -H git clone <your awesome nodejs app repository url> code

deployuserとしてコマンドを実行するために sudo -u deployuser -H ... といった形にコマンドがなっています。それからgit cloneの第2引数にcodeという文字列を渡しているのでクローンしたリポジトリのディレクトリ名はcodeになります。

Node.jsをインストールする

コードをクローンするだけではNode.jsアプリは動きません。Node.jsランタイムを入れていきます。今回は宗教上の理由でanyenvからのnodenvからのnode16系を入れます。RTAなのでapt install nodejsで適当なNodeを入れればよいのは確かです。

ローカル開発環境にはanyenvanyenv-updatenodenv-yarn-installを脳死でいつも入れてます。

Node.jsのインストール完了後、ローカルでやるのと同じ通りにプロジェクトのルートへ行き、npm i && npm startを実行します。(環境によってコマンドは変わると思います)

一旦、実行したままにしておきます。

リバースプロキシの設定をする(その1)

現状でNginxの設定を弄り、リバースプロキシの設定をします。新しく端末を開き、VPSに接続します。

以下の内容で/etc/nginx/conf.d/nodejsapp.confを作成します。

server {
        client_max_body_size 50M;
        server_name <サーバーのグローバルIPアドレス>;
        location / {
                proxy_pass http://localhost:8000; # nodeアプリが待機しているアドレス
        }
}

Nginxの設定を再読み込みします。

systemctl reload nginx

グローバルIPアドレスにアクセスしてnodeアプリが応答することを確認します。

http://<your-server-ip>/

アプリをデーモン化する

動かし続けるために端末を一個犠牲にするなんてことはしたくないので裏側で起動させるための設定をしていきます。systemdの仕組みを利用します。

https://qiita.com/bluesDD/items/eaf14408d635ffd55a18

一旦、nodeアプリが動いている端末に戻り、ctrl+Cで停止させてください。

以下のような内容を /etc/systemd/system/nodejsapp.serviceに記述します。

[Unit]
Description=cicd handson js sample app
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/home/deployuser/.anyenv/envs/nodenv/shims/node /var/www/azure-web-app-js/code/bin/www
Working/Directory=/var/www/nodejsapp/code
KillMode=process
Restart=always
User=deployuser
Group=deployuser

[Install]
WantedBy=multi-user.target

以下のコマンドでnodeアプリを起動できるようになります。

systemctl start nodejsapp

改めてグローバルIPで挙動を確認します。

systemd化のために参考にしたサイト↓

https://qiita.com/you21979@github/items/588bddb59378ce7303a2

ドメインを紐付ける

IPアドレスで直接アクセスするのはダサいのでドメインを紐付けます(個人の意見です)

ドメインを管理しているサービスで例えば以下のようなレコードを追加します。

レコード名レコードタイプ
js.yukinissie.com (your domain)A118.27.22.88 (your-server-ip)
DNSに登録するレコードの例

リバースプロキシの設定をする(その2)

ドメインを紐付けたのでNginxの設定を変更し、ドメインからのアクセスをNodeアプリに中継するようにします。/etc/nginx/conf.d/nodejsapp.confを以下のコードに修正します。

server { 
        client_max_body_size 50M;
        server_name js.yukinissie.com; # 変更点。ここは人によって異なる
        location / {
                proxy_pass http://localhost:8000; # nodeアプリが待機しているアドレス
        }
}

ドメインでアクセスできるようになりました。

SSL化する

httpじゃなくてhttpsにして通信内容を暗号化し情報を守る仕組みですね。

今どきSSL化されてないとかダサいとしか言いようがないのでします。(個人の偏見です)

無料で且つ自動的に発行を行うためにcertbotを使います。証明書の発行自体はLet’s Encryptが使われます。以下のコマンドでcertbotを入れます。(snapが入っている前提です)

snap install core && snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

そして以下のコマンドを打ってcertbotを実行します。

certbot --nginx

いくつかの質問を対話的に答えることでSSLの設定が完了します。

certbotを実行しているときの様子

これでSSL化ができます。(うまく行かないときはNginxをreloadすると動くかもしれません)

https://js.yukinissie.com/

ちなみにcertbotがNginxの設定を自動的に書き換えてくれるのでSSL化させたドメインでアクセスできるようになる仕組みです。/etc/nginx/conf.d/nodejsapp.confを改めて見るとその痕跡がみれて勉強になります。

SSL化のためにみたドキュメント↓

https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal

ようやくデプロイができました!!!!🚀

RTAに掛かった時間は、、

1時間50分でした!うん、長い!!

感想

やっぱりクラウドサービスって偉大なんだなって思いました。。


投稿日

カテゴリー:

投稿者:

タグ: