1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

HerokuにPERNアップをデプロイする流れ

Last updated at Posted at 2021-04-20

背景 

対象 

  • これが分からなかった自分に向けて書いていますので、PERNアプリは作ったが、デプロイは初めてという方むけです。:grinning:

###環境 

  • React.js, Express, Postgresql, Node.js, yarnなど。ハードはWindows PC。

###条件 

  • Github、Herokuのアカウントは作成ずみ。

###ファイル構成 

  • client側はreact-create-appで作り、clientとserverというフォルダーに分けて内容を作成。それぞれでyarn initをしてpackage.jsonがある。これをデプロイしていきます。

##0. 全体の流れ

ここで紹介するデプロイの流れは大まかに言って以下の通りです。

  1. Herokuがアプリに入る入口を準備
  2. Herokuが読むstaticファイルを準備
  3. ポートの準備(Proxyを含む)
  4. Heroku上のPostgresqlとつなぐ準備 *
  5. Node.jsとyarn/npmのバージョンを指定
  6. 違ったURLが入力されたときの対応を準備
  7. Heroku上でPostgresqlを作る *
  8. gitとHerokuを繋いでデプロイ!

"*"印はPostgresqlを使わないアプリは必要なし。では、参りましょう。

1. Herokuがアプリに入る入口を準備。

Herokuはこのアプリに入るとき、まず、ルートディレクトリにあるserver側のpackage.jsonを見ます。つまり、server側のpackage.jsonがルートディレクトリにないといけません。

私の場合はserverフォルダーを作り、その中にpackage.jsonが入っていましたので、これでは見つかりません。そこで、server側のファイルをすべてルートディレクトリに移しました。

  • 最初のディレクトリ構成
root/
  ├ client/
  │   ├ 色々/
  │   ├ 色々/ 
  │   └ package.json  
  │  
  └server/
      ├ 色々/
      ├ 色々/ 
      └ package.json
  • 変更後のディレクトリ構成
root/
  ├ client/
  │   ├ 色々/
  │   ├ 色々/ 
  │   └ package.json  
  │
  ├ 色々/
  ├ 色々/ 
  └ package.json  

これでHerokuがserver側のpackage.jsonを読めるようになりました。:thumbsup:

2. gitの設定

まだしていないなら、git initしておきます。(不安ならもう一度してOK)

ここで、.gitファイルが、このアプリ全体の中で一つだけ、そして、ルートディレクトリにあることを確認します。私は、Windowsの場合はターミナルで隠しファイルを出す方法が分からなかったので(💦)エクスプローラーでチェックしました。clientフォルダーに.git fileがあったら削除してください。

3. staticファイル(= build)を作る。

Herokuが読み込むのは「staticファイル(静的ファイル、buildとも言う)というモノ」なので、まずそのstaticファイルを作らなければなりません。ローカルで開発しているとき書いているpublicフォルダーに入っているコードから、staticファイルを作ることをbuildすると言います。

create-react-appでクライアント側を作った場合、package.jsonの中のscriptsの中に、buildするscriptがあるのでこれを使います。

具体的には、clientフォルダーにcdして、ターミナルで yarn build

これで、レポジトリ内にbuildができています。中を開いてみると、publicフォルダーの各ファイルの内容がぎっしり入ったファイルがあります。この中にhtmlも含まれていて、Herokuはこれを表示します。

##4. Herokuにbuildの指示をする。

さて、今は自分でbuildをしたわけですが、Heroku上では自動的にbuildされないといけないので、Herokuがまず最初に読むserver側のpackage.jsonに、その指示を書いておきます。

scriptsの中に「clientに入って、dependenciesを導入して、buildして」という一文を加えます。

"scripts": {
"start": "node index.js",
"heroku-postbuild": "cd client && yarn && yarn build" //←これを加える。
},

4. staticの場所をHerokuに伝える。

上のscriptでstaticができるわけですが、Herokuがserverのメインファイル(package.jsonにあるmainのファイルと名前を揃えておく)を読み込んでいくときに、そのstaticがどこにあるというのを伝えます。

その指示の際、pathというものを使います。そもそもNode.jsに入っているのでdependencyとしてyarn addとかしなくてOKで、ただファイルの頭のところで以下の一行を足します。

const path = require("path");

そして、以下のように本番はstaticを使うよう、また場所はどこかを教えます。ちなみにdirnameはdirectory nameのことなので、ルート名/client/buildにあるよ、ということです。)

if (process.env.NODE_ENV === "production"){
    app.use(express.static(path.join(__dirname, "client/build")))
}

5. PORTの準備。(サーバー側)

ローカルで開発中、serverが走っているポートは例えばlocal host 5000だったりするわけですが、Herokuにしたらそんなのどこ?!です。本番用のポートはprocess.env.PORTと書けばHerokuはわかるので、今まで5000などと書いていたら、以下のように書き換えます。

まずPORTという変数を作ります。下の一行をファイルの最初のほうで足します。PORTと言ったら、まずはHerokuの使うポートを探して、なかったら(=ローカル環境ということなので)5000を使ってね。という意味です。

const PORT = process.env.PORT || 5000 

そして、app.listenのところを、

app.listen(PORT, () => {
  console.log(`Server is starting on port ${PORT}`);
});

と書き換えます。

6. proxyの準備。(クライアント側)

portについて今度はclient側で準備します。clientからバックエンドにアクセスるときのポートについて、ローカル環境中ではこのポートと伝えつつ、同時に、Herokuには本番で使われるべきportを使うように伝えます。

やり方は、client側のpackage.jsonの末尾にproxyというのを設定して、そこにローカル環境で使うポートを書きます。

  "proxy":"http://localhost:5000"
}

proxy設定をしたので、clientのファイルにあるhttp://localhost:5000は削除します。残ったコードは"/""/xxx"のような形になります。

7. クライアントをリフレッシュ

この段階でアプリを表示し、入力して動かそうとすると、proxyが効かずエラーが発生します。(clientがloalhost:3000で走っていた場合は"/"がproxyで設定したポートではなくlocalhost:3000になってしまう。)
そこでproxyを加えた変更を活かすために以下の手順を行います。

  1. client側のnode_modulesとyarn.lockをいったん削除。
  2. もういちどdependenciesを導入。
  3. clientを再起動。

8. .envを準備する。(データベースを使う場合に必要)

  1. server側でdotenvを導入する。

2. .envファイルを作る。ただ以下の通りに書きます。jsファイルではないのでrequireも何もいりません。

 PG_USER = postgres
 PG_PASSWORD = xxxxxx
 PG_HOST = localhost
 PG_DATABASE = xxxxxx
 PG_PORT = 5432

**コロン(:)ではなくイコール(=)**を使います。

git add, git commitをする前に.envを.gitignoreに入れてgit管理下に置かないようにします!

でも、大丈夫:grinning:。もし誤ってgit管理下に入れてしまったときには、

git rm --cached [name of file] 

としておいて、git add, commit, pushしてください。

9. 本番時、Heroku上のpostgresqlとつながるよう設定。(Postgresqlを使う場合のみ必要)

開発中は.envに書いたデータをもとにローカルのpostgresqlにアクセスし、本番中はprocess.env.DATABASE_URL、つまり、Heroku上で設定するpostgresqlにアクセスするように書きます。

devConfigはローカルのpostgresqlデータベース、proConfigは本番環境のアクセス先で定義し、本番のときはproConfigにアクセスしてね、と指示します。

さらにSetting SSL~の部分は、Herokuの場合、Postgresqlを使うときにはSSL接続が必要だからです。これは別記事の「ローカルで動くNode.jsとPostgresqlを使ったアプリがHerokuだと動かないときに解決できた方法」にまとめています。

これができていないと、fetchがうまくいきません。:scream:

const Pool = require("pg").Pool;
require("dotenv").config(); // これで.envのデータが読めるようになる。

const devConfig = `postgresql://${process.env.PG_USER}:${process.env.PG_PASSWORD}@${process.env.PG_HOST}:${process.env.PG_PORT}/${process.env.PG_DATABASE}`

const proConfig = process.env.DATABASE_URL

const pool = new Pool({
    connectionString : process.env.NODE_ENV === "production" ? proConfig : devConfig,
    
    Setting SSL
    ssl:{
        sslmode: 'require',
        rejectUnauthorized: false
    }
})

module.exports=pool;

これで後で設定するHeroku上のデータベースとつながります!:ok_woman:

10. Node.jsとyarn/npmのバージョンを指定。

開発中使ったのと違うバージョンのNode.jsやyarn/npmが、本番環境で使われてエラーの元とならないよう、開発中と同じバージョンを使ってください、と指示するため、server側のpackage.jsonにengines(engines 複数!)というものを足します。

{
  "name": "xxxxx",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "engines":{            //この三行です。バージョンはターミナルでnode -v、yarn -vで調べます。
    "node": "12.19.0",
    "yarn": "1.22.5"
  },
  "scripts": {
    "server": "nodemon index",
    "start": "node index.js",//Add this one
    "heroku-postbuild": "cd client && yarn && yarn build" //Also this.
  },
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "nodemon": "^2.0.7",
    "pg": "^8.5.1"
  }
}

11. キャッチオールを足す。(必須ではない)

間違った末尾のURLでアクセスされた場合、トップページを返しておくように、server側、index.jsのapp.listen直前に足しておきます。

app.get("*", (req, res)=>{
    res.sendFile(path.join(__dirname, "client/build/index.html"));
})

12. Herokuの準備!

【注意】ここまで色々コードをいじっているので、git commitしておくこと!

いよいよ、Herokuの準備です。

まず、ルートディレクトリやフォルダー内の.gitignoreに.envやnode_modulesを入れているか今一度、チェック。これまで入れていなかったら、gitに入れていたということなので、
git rm --cached.env で消します!

まず、ターミナル上でHerokuにログインします。

heroku login

どんなキーでもよいので(qは出てしまうのでそれ以外)たたくとHerokuのサイトが現れるのでログイン。ターミナルに戻り、

heroku create [name of app]

これで空のアプリができました。

Heroku上でpostgreqlデータベース(無償版)を作ります。 (もちろんPostgresqlを使う場合のみ)

heroku addons:create heroku-postgreql:hobby-dev -a [name of app]

作ったデータベースに入ります。

heroku pg:psql -a [name of app]

データベース中にテーブルを作ります。

ここは通常、ターミナルでpostgreqlのテーブルと作るのと同じです。

13. Herokuとgit remoteを繋ぐ。

heroku git:remote -a [name of app]

そして、、、、

git push heroku main

以上です!お疲れさまでした。

Heroku上でアプリが出来上がりますので、実際に確認してください。:clap:

14. 今後、Heroku上のアプリを更新する際は?

ローカルでコードを更新したら、git add, git commit して

git push heroku main

でOKです!


参照した動画 How to Deploy a PERN application on Heroku

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?