概要

最近はHerokuで動かすことが多く、GitLab CIの設定も簡単なので、デプロイ自動化をモリモリ進めています。

そんな中、Node.jsアプリを自前サーバーで動かす必要が出てきて、Herokuと同じように簡単にデプロイしたいなー、と思い色々調べて自動デプロイできるようにしました!

ref.
Easy Deploy with SSH | PM2
PM2 Deployment via Gitlab CI

Step.1 PM2でローカルからデプロイ

pm2 は、Node.js用のプロセスマネージャーです。
他にも forever などがありますが、デプロイ機能が無いので、こちらを使います。

ref. PM2 Runtime - The Most Advanced Production Process Manager for Node.js

local.png

Step.1-1 SSHセットアップ

GitLab・リモートサーバーどちらもパスワードなしでSSH接続できる状態であれば、以下の設定は不要です。

SSHキーペアの生成

鍵ファイル名は任意(今回は pm2_rsa とした)

$ cd ~/.ssh
$ ssh-keygen -t rsa -f pm2_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):  ←パスワードは空
Enter same passphrase again:  ←パスワードは空

公開鍵の登録

GitLab

~/.ssh/pm2_rsa.pubを、GitLabの[プロフィール画面 > SSH Keys]に登録する。

リモートサーバー

$ ssh-copy-id -i pm2_rsa ${user}@${target_host}

${user}@${target_host}は、デプロイ先となるリモートサーバーのユーザーとホスト名

Step.1-2 インストール

※ローカル、リモートサーバーどちらにもインストールする

$ npm install pm2 -g

Step.1-3 デプロイ設定ファイルの準備(ローカル)

ファイル作成

※プロジェクトルートで実行する

$ pm2 ecosystem

ファイル修正

module.exports = {
  apps : [{
    name: 'API', // 任意のアプリ名に変更
    script: 'app.js', // 起動対象のファイル名に変更(ex. index.js)

    // Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
    args: 'one two',
    instances: 1,
    autorestart: true,
    watch: false,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'development'
    },
    env_production: {
      NODE_ENV: 'production'
    }
  }],

  deploy : {
    production : {
      user : 'node', // デプロイサーバーにSSHログインするユーザー名
      host : '212.83.163.1', // デプロイサーバーのホスト名
      ref  : 'origin/master',
      repo : 'git@github.com:repo.git', // デプロイ対象のGitリポジトリ
      path : '/var/www/development', // デプロイサーバーのデプロイ対象ディレクトリパス
      'post-deploy' : 'npm install && pm2 startOrRestart ecosystem.config.js --env production'
    }
  }
};

セットアップ

$ pm2 deploy production setup

Step.1-4 リモートサーバーへのデプロイ(ローカル)

$ pm2 deploy production

デプロイできない場合

リモートリポジトリからの git clone でエラーとなっている可能性が高いです。
SSH clone errors を参考に、パスワードなしで git clone できるようにする必要があります。

Step.1-5 デプロイできていることの確認(リモートサーバー)

プロセスの確認

$ pm2 list
┌──────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name │ id │ version │ mode │ pid   │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├──────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│   API    │ 0  │ 1.0.0   │ fork │ 10844 │ online │ 383     │ 0s     │ 0%  │ 61.8 MB   │ root │ disabled │
└──────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

対象Appの status が online であれば、OK!

Step.2  GitLab CIでデプロイ

GitLab CIを利用して、masterブランチに変更が加わったタイミングで、リモートサーバーに自動デプロイします。

ref. Using SSH keys with GitLab CI/CD | GitLab

ci (2).png

Step.2-1 .gitlab-ci.yml を定義

image: node:alpine

stages:
  - production

production:
  type: deploy
  stage: production
  before_script:
    # Install ssh-agent if not already installed, it is required by Docker.
    # (change apt-get to yum if you use a CentOS-based image)
    - 'which ssh-agent || ( apk add --update openssh )'

    # Add bash
    - apk add --update bash

    # Add git
    - apk add --update git

    # Run ssh-agent (inside the build environment)
    - eval $(ssh-agent -s)

    # Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
    - echo "$SSH_PRIVATE_KEY" | ssh-add -

    # For Docker builds disable host key checking. Be aware that by adding that
    # you are suspectible to man-in-the-middle attacks.
    # WARNING: Use this only with the Docker executor, if you use it with shell
    # you will overwrite your user's SSH config.
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
    # In order to properly check the server's host key, assuming you created the
    # SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines
    # instead.
    # - mkdir -p ~/.ssh
    # - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
  script:
    - npm i -g pm2
    - pm2 deploy production
  only:
    - master

Step.2-2 GitLabにSSHログイン用の秘密鍵登録

CI___CD_Settings_·CI___CD·00000_zyyxall___gitlabooot·_GitLab.png

Step.2-3 デプロイの確認

fixed__gitlab-ci_yml_original___20__·Merge_Requests·00000_zyyxall___gitlabooot·_GitLab2.png
production___7120__·Jobs·00000_zyyxall___gitlabooot·_GitLab.png

以上で、Node.jsアプリをGitLab CIで自動デプロイできるようになりました。