🚀

CircleCI :Agentless で Linux にデプロイを行う(2) Node.jsのインストールとWebの起動

に公開

前回の記事ではAgentlessでSSHを用いてLinuxにnginxをインストールし起動を行いました。今日はさらにそのconfig.ymlを改造し、nginxではなくnode環境のウェブを起動します。

デプロイ時に行われる作業は以下です。
1.SSHログイン
2.Nodeインストール
3.GitからNodeファイルのコピー
4.Node環境の初期設定
5.Webサーバ起動

さっそくやってみる

1. 必要ファイルの作成

server.js,package.json,nodeapp.service3つのファイルをGitレポジトリに配置します。ディレクトリは直下を使用しています。

server.js
// server.js
const http = require('http');

const port = process.env.PORT || 8080;
const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type':'text/plain; charset=utf-8'});
  res.end('Hello from Node.js on port ' + port + '\n');
});

server.listen(port, '0.0.0.0', () => {
  console.log(`Server running at http://0.0.0.0:${port}/`);
});
package.json
{
  "name": "node-hello-8080",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {}
}
nodeapp.service
[Unit]
Description=Node.js App (port 8080)
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/nodeapp
Environment=PORT=8080
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target

2. config.yml の置き換え

以下の値にconfig.ymlを置き換えます。場所は./circleci/config.ymlです。

config.yml
version: 2.1

jobs:
  deploy-nodeapp:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout

      # CircleCIに登録したSSH鍵を使用(Fingerprintで指定)
      - add_ssh_keys:
          fingerprints:
            - "SHA256:xxKOKDhqcEfxkek9slpnuS4mDrXaNRPC2eMjq1oXNBk"

      # デプロイ先サーバの known_hosts 登録
      - run:
          name: Register known_hosts
          command: |
            mkdir -p ~/.ssh
            ssh-keyscan -p 22 27.133.130.xxx >> ~/.ssh/known_hosts

      # Nodeアプリのデプロイ&起動
      - run:
          name: Deploy & start node app
          command: |
            ssh -p 22 ubuntu@27.133.130.xxx "
              set -eo pipefail

              APP_DIR=/home/ubuntu/nodeapp
              REPO_URL=https://github.com/h-kameda-sakura/apitest.git

              # 必要パッケージ
              if command -v apt-get >/dev/null 2>&1; then
                sudo apt-get update -y
                sudo apt-get install -y git curl
              elif command -v dnf >/dev/null 2>&1; then
                sudo dnf install -y git curl
              elif command -v yum >/dev/null 2>&1; then
                sudo yum install -y git curl
              elif command -v zypper >/dev/null 2>&1; then
                sudo zypper -n install git curl
              fi

              # GitHubをknown_hostsに追加
              mkdir -p ~/.ssh
              ssh-keyscan github.com >> ~/.ssh/known_hosts || true

              # Node.js(未インストール時のみ)
              if ! command -v node >/dev/null 2>&1; then
                if command -v apt-get >/dev/null 2>&1; then
                  curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
                  sudo apt-get install -y nodejs
                elif command -v dnf >/dev/null 2>&1; then
                  curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
                  sudo dnf install -y nodejs
                elif command -v yum >/dev/null 2>&1; then
                  curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
                  sudo yum install -y nodejs
                elif command -v zypper >/dev/null 2>&1; then
                  curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
                  sudo zypper -n install nodejs
                else
                  echo Unsupported OS >&2; exit 1
                fi
              fi

              # 初回クローン or 更新
              if [ -d \"\$APP_DIR/.git\" ]; then
                git -C \"\$APP_DIR\" fetch --all
                git -C \"\$APP_DIR\" checkout main
                git -C \"\$APP_DIR\" pull --ff-only
              else
                sudo mkdir -p \"\$APP_DIR\"
                sudo chown -R ubuntu:ubuntu \"\$APP_DIR\"
                git clone \"\$REPO_URL\" \"\$APP_DIR\"
              fi

              cd \"\$APP_DIR\"
              npm ci || npm install

              # ユニットファイルを設置(リポジトリにnodeapp.serviceがある前提)
              if [ -f nodeapp.service ]; then
                sudo install -m 0644 nodeapp.service /etc/systemd/system/nodeapp.service
                sudo systemctl daemon-reload
                sudo systemctl enable nodeapp
              fi

              # サービス再起動
              sudo systemctl restart nodeapp || sudo systemctl start nodeapp
              sudo systemctl status nodeapp --no-pager || true
            "

workflows:
  deploy:
    jobs:
      - deploy-nodeapp

3. テスト

ファイルをマージするたびに毎回Deployが走っているはずです。


ブラウザでアクセスを行えば無事起動していることが確認できます。

Discussion