By U Zensen.

欲しいものはプログラミングで自分で作る。

node.jsで作ったアプリをHerokuで公開する!!

2016 / 10 / 15 2016 / 10 / 19
JavaScript
161015_title

はじめに!!

どうも!自称node.js使い、ぴーすけです!

以前より、node.jsで作成していたリアルタイムチャットアプリをHerokuというWEBサービスを使ってネット上に公開しました!

アプリ自体は大したことないですがHerokuでnode.jsを使ったアプリを公開する方法がわかったので、記事にしたいと思います。

スポンサードリンク

Herokuとは

heroku

HerokuとはWEBアプリを簡単に公開するためのWEBサービスです。

公式サイト
Heroku

WEBアプリを公開するためには、サーバーを借りたり、ドメインを借りたり、他にも色々とにかく大変です。

Herokuは、それらの面倒くさいことを代わりにやってくれるサービスになっています。

なので、こちらはとにかくWEBサービスを作るだけで良いんです。便利!!全部英語だけど便利!!

前提

必要なものとしては

  • 公開するシステムやサービス
  • gitが使用可能なこと
  • npmが使用可能なこと(node.jsを使いたいので)

まず、公開するサービスを作ってあることが前提です。今回私は以前node.jsとexpressを使ってルーム機能のあるリアルタイムチャットを作る!!で作ったリアルタイムチャットアプリを公開します。実装にはnode.jsとexpressを使っています。

そして、gitが使えるようになっていることが前提です。gitはGit – Gitのインストールなどを参考にインストールしておいてください。

npmは、サーバー上でnode.jsを使うための設定ファイル作成時に必要になります。node.jsを使わない方は不要かもしれません。

ちなみに、今回WEBサーバーに上げるアプリはnode.jsとexpressを使ってルーム機能のあるリアルタイムチャットを作る!!で作ったリアルタイムチャットアプリを公開しますが、WEB上に上げるにはそのままでは動きませんでした。なので、この記事で作ったファイルの一部を修正しています。修正は1ファイルの1行だけ。それは以下です。

chat.js

var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var POST = process.env.PORT || 8080;//ここを修正 //以下省略

ここだけ直せば、WEB上にあげてもちゃんと動くはずです。

流れ

Herokuに登録

Herokuでアプリを作る

デプロイする予定のディレクトリで設定ファイルを作る

Herokuのアプリとデプロイ予定のディレクトリを紐付ける

gitでコミットしてプッシュ

完成

Herokuに登録する

では早速、公式サイトからHerokuに登録しましょう!

トップページから「Sign Up」します。

161015_1

会社名以外は必須です。今回は開発言語と「node.js」にしました。

161015_2

完了画面は以下の感じ。でもまだ完了していません!メールがすぐ来ているのでそれを見に行きましょう。

161015_3

メール内のURLを叩くと以下の画面に遷移します。パスワードを設定しましょう!

161015_4

これで本当に完了!以下をクリックするとマイページに遷移します。

161015_5

Herokuでアプリを作る

次はとりあえずHeroku上でアプリを作ります。

以下のボタンを押します。

161015_6

アプリ名は重複できないので、ちゃんと考えないといけません。空のままで「Create App」を押すと、自動で値を作ってくれるので、とりあえずはそれでもいいかもしれません!

161015_7

Heroku Toolbeltをインストールする

最後にコマンドラインでHerokuを使うためのツールをインストールします。

以下をクリック!

161015_8

私の場合はmacを使っているので、「OS Xバージョン」をインストールしました。

161015_9

ボタンを押すとインストーラをダンロードできるので、あとはそのインストーラの指示通りにインストールすればOKです。

npmで設定ファイルを作る

さあ、ここからは実際にアプリを公開する手順になります。

以下は私の作ったアプリの構成になっています。

161012_1

まずは「chatディレクトリ」に移動し、「npmコマンド」を使って、node.jsに関する設定ファイルを作ります。

cd {パス}/chat
npm init

上記コマンドを入力すると、色々聞かれます。基本的には特に入力せずにEnterでOKです。どうせ後で書き直せますからね。

一応以下の質問には、適切な値を入力しておきましょう。

//その他の質問
description: {何かしらの説明文} 例) realtime chat
//その他の質問
test command: {実行コマンド} 例) node chat.js 
//その他の質問
author: {作成者名} 例) byuzensen
//その他の質問

そうすると、最後に以下のように確認を取られるのでEnterを押して許可しましょう。

{
  "name": "アプリ名",
  "version": "0.0.0",
  "description": "realtime chat",
  "main": "chat.js",
  "dependencies": {
    "express": "^4.11.1",
    "socket.io": "^1.3.2",
  },
  "devDependencies": {}
  "scripts": {
    "test": "node chat.js",
  },
  "author": "byuzensen",
  "license": "ISC"
}

OKを押すとchatディレクトリ上に「pakege.json」ファイルが作成され、先ほど確認した内容が書かれています。

早速ですが、作成したファイルを少し書き直します。

{
  "name": "アプリ名",
  "version": "0.0.0",
  "description": "realtime chat",
  "main": "chat.js",
  "dependencies": {
    "express": "*",//ここの値を*に
    "socket.io": "*",//ここの値を*に
  },
  "devDependencies": {}
  "scripts": {
    "start": "node chat.js",//ここのキーをtestからstartに
  },
  "engines": {//ここ追加
    "node": "0.11.11"//ここ追加(自分のnodeのバージョンを調べて入れる)
  },//ここ追加
  "author": "byuzensen",
  "license": "ISC"
}

これで保存でnode.js周りの設定は完了です。

最後の事前準備

最後に2つのファイルを作成します。(あれば中が合っているか確認してください)

chatディレクトリ上に「.gitignore」という名前のファイルと「Procfile」という名前のファイルをを作成して中に以下の内容記述して保存します。

.gitignore

node_modules

gitignoreには、今後中身が変更されないであろうファイルやディレクトリを指定しておきます。こうしておくとgitがそのファイルを無視するようになるので、無駄がなくなります。

Procfile

web: node chat.js

ProcfileはHeroku上で実行するコマンドを書いておく必須のファイルです。

gitを使ってHerokuにアプリをデプロイする

まずはHerokuにログインします

heroku login

chatディレクトリに移動し、gitを使う準備をします。そしてHerokuから先ほど作ったアプリのリポジトリを取得します。

cd {パス}/chat
git init
heroku git:clone -a アプリ名

そして、chatディレクトリのファイルをすべて追加し、コミットし、プッシュします。

git add .
git commit -m "commit comment!"
git push heroku master

これで、chatディレクトリの内容がHerokuで作ったアプリにデプロイされます。

動かす

コマンドラインから以下のコマンドを入力するとブラウザでページが立ち上がります。

heroku open

または、Herokuの管理画面上から「Open App」 を押しても表示されます。

今回できたやつ
byuzensen-chat

わーい!自分で作ったアプリがWEB上でアクセスできる!!

ちなみに。一応WEB上に上げるということで、少しクライアントサイドとサーバーサイドのファイルを修正しています。(自分のIDを確認できたり、現在のアクセス数を確認できるように修正した)

最終的に本番にあげたファイルはこんな感じ

index.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <title>byuzensen chat | node.jsとexpressで作ったリアルタイムチャットをHerokuで公開した</title> <style> * { padding: 0; margin: 0; box-sizing: border-box; } body { font-family: Verdana; } ul { list-style-type: none; padding: 20px; background: #000; color: white; } #controls { position: absolute; bottom: 0px; left: 0px; padding: 20px; display: block; width: 100%; } #controls #msj { float: left; width: 78%; display: block; padding: 20px; border-radius: 5px; } #controls #btn { float: right; width: 20%; height: 57px; display: block; background: white; border: 1px solid #aaa; font-size: 1.4em; border-radius: 5px; } #controls #channel { display: block; width: 100%; font-size: 1.2em; padding: 20px; background: white; margin-bottom: 10px; height: 45px; } #info { padding: 15px 10px; background: #efefef; } #user_name p, #user_cnt p { display: inline-block; } </style> <script src="/socket.io/socket.io.js"></script> <script src="//code.jquery.com/jquery-1.11.1.js"></script> </head> <body> <script> <!-- サーバー側とつなぐため --> var socket = io(); $(function() { <!-- 送信されたときの処理 --> $('form').submit(function() { <!-- メッセージを取得 --> var mensaje = $('#msj').val(); <!-- メッセージがなければ終了 --> if (mensaje === '') return false; <!-- メッセージを送信 --> socket.emit('message', mensaje); <!-- メッセージの中身を空にしえフォーカスする --> $('#msj').val('').focus(); return false; }); <!-- チャンネルを変えた時の処理 --> $('#channel').on('change', function() { <!-- チャンネル変更する --> socket.emit('change channel', $('#channel').val()); }); }); <!--ここで作ったイベント名でサーバーサイドの処理を紐付ける--> socket.on('welcome', function() { <!-- 取得したメッセージをulに追加 --> $('#message').append($('<li>').text('ようこそ!!')); }); socket.on('user cnt', function(cnt) { <!-- 取得したメッセージをulに追加 --> $('#user_cnt p').html('').text("(A :" + cnt.a +"人) (B :" + cnt.b + "人)"); }); socket.on('message', function(msj, id) { <!-- 取得したメッセージをulに追加 --> $('#message').append($('<li>').text(id + " : " + msj)); }); socket.on('change channel', function(channel) { <!-- チャンネルが変わったことをメッセージで表示 --> $('#message').html('').append($('<li>').text('「チャンネル' + channel + '」に変更されました!')); }); socket.on('get id', function(id) { <!-- チャンネルが変わったことをメッセージで表示 --> $('#user_name p').html('').text(id); }); </script> <div id="info"> <div id="user_name">あなたのID&nbsp;:&nbsp;<p></p></div> <div id="user_cnt">アクティブユーザ&nbsp;:&nbsp;<p></p></div> </div> <ul id="message"></ul> <div id="controls"> <form action=""> <select name="channel" id="channel"> <option value="A">チャンネルA</option> <option value="B">チャンネルB</option> </select> <input type="text" id="msj" placeholder="メッセージを入力してください..."> <input type="submit" id="btn" value="送信"> </form> </div> </body> </html>

chat.js

var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var POST = process.env.PORT || 8080; var userCnt = { a : 0, b : 0 } //ルートディレクトリにアクセスした時に動く処理 app.get('/', function(req, res) { //index.htmlに遷移する res.sendFile(__dirname + '/index.html'); }); //socket.ioに接続された時に動く処理 io.on('connection', function(socket) { //接続時に振られた一意のIDをコンソールに表示 console.log('%s さんが接続しました。', socket.id); var channel = 'A';//デフォルトのチャンネル socket.join(channel);//Roomを初期化するらしい userCnt.a++;//アクセス時はデフォルトのチャンネルなので、そのユーザをカウント io.emit('user cnt', userCnt);//全ユーザ上のユーザ数を更新 //「ようこそ」と「ID」を自分の画面だけに表示 socket.emit('welcome'); socket.emit('get id', socket.id); //接続時に同じチャンネルの人に入室を伝える socket.broadcast.to(channel).emit('message', socket.id + 'さんが入室しました!', 'system'); //messageイベントで動く //同じチャンネルの人にメッセージを送る socket.on('message', function(msj) { io.sockets.in(channel).emit('message', msj, socket.id); }); //接続が切れた時に動く //接続が切れたIDを全員に表示 socket.on('disconnect', function(e) { console.log('%s さんが退室しました。', socket.id); if (channel === 'A') { userCnt.a--; } else { userCnt.b--; } //アクティブユーザを更新 io.emit('user cnt', userCnt); }); //チャンネルを変えた時に動く //今いるチャンネルを出て、選択されたチャンネルに移動する socket.on('change channel', function(newChannel) { socket.broadcast.to(channel).emit('message', socket.id + 'さんが退室しました!', 'system');//ルーム内の自分以外 if (newChannel === 'A') { ++userCnt.a; if (userCnt.b > 0) { --userCnt.b; } } else { ++userCnt.b; if (userCnt.a > 0) { --userCnt.a; } } io.emit('user cnt', userCnt); socket.leave(channel); //チャンネルを去る socket.join(newChannel); //選択された新しいチャンネルのルームに入る channel = newChannel; //今いるチャンネルを保存 socket.emit('change channel', channel); //チャンネルを変えたこと自分に送信 socket.broadcast.to(channel).emit('message', socket.id + 'さんが入室しました!', 'system');//ルーム内の自分以外 }); }); //接続待ち状態になる http.listen(POST, function() { console.log('接続開始:', POST); });

参考

今回の実装に当たって参考になった動画とサイトです。

Herokuにnode.jsのアプリを上げる方法

socket.ioの使い方

以上!!

以上です!今回初めてHerokuを使いました。すべて英語なので取っつきにくいですが、一つ一つやっていけばなんとか公開することができました!

みなさんもぜひ試しにやってみてください!

Pocket

コメント

コメントを残す