Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
61
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@yfujii01

GCP(GCE)にNode.jsアプリケーションをデプロイする

可能な限りお金は使わない方向で実現したいと思います。

手順一覧

  1. gce(Google Compute Engine)のインスタンス作成
  2. nginxを設定してhttp接続できるようにする
  3. ドメインをfreenomで作る
  4. Let's Encrypt でSSL証明書を作る
  5. アプリをnodejsで作る
  6. nginxの設定を修正しアプリをhttps接続できるようにする

gce(Google Compute Engine)のインスタンス作成

  • GCPにログインします
    https://cloud.google.com/

  • Compute Engineのインスタンスを作成する
    ダッシュボードからCompute Engineを選び、VMインスタンス、インスタンスを作成と進みます。
    image.png

  • 名前を適当に決めます
    デフォルトのままでも良いです。
    image.png

  • リージョンをus-west1 (オレゴン)にします。
    初期設定の「us-east1 (サウスカロライナ)」でも問題ありません。
    多少は応答が速くなるかもという思いから日本に少しでも近い「us-west」に変更しました。
    image.png

  • マシンタイプを「micro (共有 vCPU x 1)」に変更します
    毎月無料枠に収めるためには必須の作業になります。
    image.png

  • ブートディスクのサイズを30GBに変更します
    任意作業です。デフォルトでは10GBだが、30GBまで無料なのでとりあえず変更するくらいでOKです。
    image.png

  • ファイアウォールを設定します
    HTTPとHTTPSを許可します。
    image.png

  • 確定
    「作成」を押下しインスタンスを作成します。
    image.png
    少し待つと、インスタンスが作成されました。
    image.png

nginxを設定してhttp接続できるようにする

  • 「ブラウザウィンドウで開く」を押下しgceインスタンスに接続します image.png

image.png

  • nginxをインストールします
$ sudo apt install nginx -y
  • nginxのサービスを起動します
$ sudo service nginx start
  • 動作確認します
    gceインスタンスの外部IPを確認し、httpで接続してください。
    image.png 以下のようにWelcome to nginx!と表示されたらOKです。 image.png

httpsはまだ設定していないのでエラーになります。
image.png

ドメインをfreenomで作ります

URL
https://www.freenom.com/ja/index.html?lang=ja

  • ユーザー登録してサインインします。
    Googleアカウントでログインする方が簡単で良いかも。

  • 「Services > Register a New Domain」からドメイン取得画面に移動する
    image.png
    image.png

  • 使いたいドメイン名を入力します
    今回は「f01api」と入力して「Check Availability」ボタンを押しました。
    短か過ぎるドメイン名だと0円にならないことがあるので、必ず「USD0.00」になっていることを確認しましょう。
    image.png

  • ドメイン名の最後につける文字列を「.tk」「.ml」などから選択します
    今回は「.tk」と「.ml」の2つを選択してみます。
    2つ取得する意味は特にありません(偽サイト対策程度の意味はありますが)。
    それぞれ「Get it now!」を選択し、その後「Checkout」を選びます。
    image.png

  • DNS設定を行います
    ドメイン名とIPアドレスを紐づけます。
    「Use DNS > Use Freenom DNS Service > IP address」に使用するgceインスタンスの外部IPを設定します。
    今回は「.tk」「.ml」に同じIPを設定しました。
    後から変更も簡単に行えるのであまり気にしなくても大丈夫です。
    設定できたら「Continue」を押しましょう。
    image.png
    image.png

  • 確定する
    Total Due Todayが$0.00USDになっていることを確認し、
    最下部にある「I have read and agree to the Terms & Conditions」をチェックし「Complete Order」を押しましょう。
    image.png
    image.png
    「Order Confirmation」となれば成功です。
    image.png

  • domain一覧を確認する
    「Services > My Domains」を開くことでちゃんと購入できているか確認できます。
    image.png

  • 動作確認します
    もしかすると購入直後はDNSが設定されておらずエラーになってしまうかもしれませんが、5分も経てば購入したドメインでnginxの画面が表示されるはずです。
    image.png
    image.png

Let's Encrypt でSSL証明書を作ります

公式の手順書があるのでこちらを参考に進めていきましょう。
https://letsencrypt.jp/docs/using.html

  • cerbot-autoをインストールします
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
  • cerbot-autoを実行します
    途中で何度か止まるので適宜、入力していきます。
$ ./certbot-auto
  • Emailを入力します
    image.png

  • 利用規約を確認します
    URL
    https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
    確認後「A」を入力します。
    image.png

  • Emailにお知らせを送って良いかを選択します
    「N」を選択しました。
    image.png

  • SSL証明書を発行したいドメインを入力します
    「f01api.tk」を入力しました。
    image.png

  • httpをhttpsにリダイレクトするかの設定
    「2」(リダイレクトする)を選択しました。
    image.png

  • 証明書の発行に成功
    image.png
    それぞれ以下にファイルが作成されたようです。

    • 証明書
      /etc/letsencrypt/live/f01api.tk/fullchain.pem
    • 秘密鍵
      /etc/letsencrypt/live/f01api.tk/privkey.pem
  • https接続の確認をする
    cerbot-autoのおかげでnginxの設定が書き換えられ、https://【ドメイン名】で接続が行えるようになっています。
    確認してみましょう。
    image.png

アプリケーションをNode.jsで作る

Node.jsをインストールします
$ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
$ sudo apt-get install -y nodejs
インストールされたことの確認します(バージョン確認)
$ node --version
v10.11.0
ディレクトリ作成
$ cd ~
$ mkdir express-api
$ cd express-api
npm初期化
$ npm init -y
npmでexpressとbody-parserをインストール
$ npm i --save express body-parser 
  • アプリを作成する
index.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.get('/', (req, res) => res.send('Hello World!'));

app.post('/test', (req, res) => {
    let result = {};
    if (req.body.password === 'hoge') {
        result.result = "true";
    } else {
        result.result = "false";
    }
    res.json(result);
});

app.listen(3000);
  • デーモン起動のためにforeverをインストールする
foreverインストール
$ npm i --save-dev forever
  • scriptに起動・停止設定を追加する
$ vi package.json
変更前
:
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
},
:
変更後
:
"scripts": {
  "start": "forever start index.js",
  "stop": "forever stop index.js",
  "test": "echo \"Error: no test specified\" && exit 1"
},
:
アプリを起動する
$ npm run start

> express-api@1.0.0 start /home/hoge_gmail_com/express-api
> forever start index.js

warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: index.js
  • 動作確認する
    nginxを通していないので「http://【外部IP】:3000」で接続します。
    image.png

  • 停止方法
    もしアプリを修正することになって止めたい場合は、以下のコマンドを実行します。

アプリ停止
$ npm run stop

> express-api@1.0.0 stop /home/hoge_gmail_com/express-api
> forever stop index.js

info:    Forever stopped process:
    uid  command       script   forever pid   id logfile                                   uptime
[0] b-8D /usr/bin/node index.js 20695   20702    /home/hoge_gmail_com/.forever/b-8D.log 0:0:0:33.898

nginxの設定を修正しアプリをhttps接続できるようにする

$ sudo vi /etc/nginx/sites-available/default
変更前
server {
    :
    server_name f01api.tk; # managed by Certbot
    :
    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
    :
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    :
}
変更後
server {
    :
    server_name f01api.tk; # managed by Certbot
    :
    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;
        proxy_pass http://127.0.0.1:3000;
    }
    :
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    :
}
nginx再起動
$ sudo service nginx restart
  • 動作確認
    https://【ドメイン名】で接続するとnginxの設定画面ではなくhello worldが表示(アプリの画面)が表示されること
    nginxのページが表示される場合はブラウザのキャッシュを消してから確認してみてください。
    image.png

  • 動作確認2
    curlを使ってアプリが動作するか確認しましょう。
    今回作成したアプリはpasswordをjson形式で渡すことでresultをjson形式で返すものです。
    テスト用なので{"password":"hoge"}という文字列を渡すことで、trueを返し、それ以外の場合はfalseを返すようになっています。

trueパターン
$ curl -X POST https://f01api.tk/test -H "Content-type: application/json" -d '{"password":"hoge"}'
{"result":"true"}
falseパターン
$ curl -X POST https://f01api.tk/test -H "Content-type: application/json" -d '{"password":"fuga"}'
{"result":"false"}

想定通り返ってきました。

これで完成です。
お疲れ様でした。

61
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
61
Help us understand the problem. What is going on with this article?