2
0

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 1 year has passed since last update.

IBM Cloud Code Engine に React + Express アプリケーションをデプロイしてみる

Posted at

はじめに

前回の記事でIBM Cloud Code EngineにPlay Framework/Scalaアプリケーションをデプロイする方法を紹介しましたが、今回は同様のプロセスをNode.jsベースのアプリケーションでも行なってみます。このNode.jsアプリケーションはフロントエンドにReactを用い、バックエンドにはExpressを使ってサーバーを構築します。プロダクションへのデプロイ時にはバックエンドのExpressサーバーが両方ともホストすることになります。(ネット上にこの構成でクラウド環境へのデプロイまでカバーしている記事があまり多くはなかったので記述しておくという意味合いもあります。)

Expressサーバーの構築

Expressサーバーを構築するのにexpress-generatorを使用します。

$ npm i -g express-generator

早速Expressサーバーの雛形を作成します。

$ express react-express

最終的にフロントエンドはReactで書くことになるので、ここではテンプレートエンジンの設定等を除いていきます。まずpublicviewsディレクトリは削除します。次にpackage.jsonから以下の行を削除します。

package.json
    "jade": "~1.11.0",

次にapp.jsからも以下の行を削除します。

app.js
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

indexRouter関連の行も削除して構いません。また、後述のReactアプリケーション側とポートが衝突しないように、bin/wwwも変更しておきます。

bin/www
var port = normalizePort(process.env.PORT || '8080');
app.set('port', port);

これだけで既にweb application serverとして起動できます。

$ npm i
$ npm start

> react-express@0.0.0 start
> node ./bin/www

ブラウザからlocalhost:8080/usersにアクセスして確認すると以下のようになります。

スクリーンショット 2021-12-28 13.51.06.png

Reactアプリケーションの作成

ReactアプリケーションをCreate React Appを使って作っていきます。最終的にclient以下にReactのコードを配置したいので、ディレクトリ名をclientとするため以下のコマンドで作成します。

$ npx create-react-app client

出来上がったらclientディレクトリに移動してnpm startすると見慣れたトップページが表示されます。
スクリーンショット 2021-12-28 13.28.33.png

これでExpressサーバーとReactアプリケーションが起動していますが、ばらばらに動いている状態です。これを接続するため、まずはproxyの設定をします。client/package.jsonproxyを定義します。

client/package/json
  "proxy": "http://localhost:8080",

client/src/App.jsを改変して/users/を呼び出して結果を表示するように変更します。

client/src/App.js
import logo from './logo.svg';
import './App.css';
import {useState, useEffect} from 'react';

function App() {
  const [users, setUsers] = useState('');
  useEffect(() => {
    fetch('/users/')
      .then((res) => res.text())
      .then((text) => setUsers(text));
  }, []);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello {users}!
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

ブラウザ上で表示を確認します。

スクリーンショット 2021-12-28 14.17.32.png

プロダクション用の構成

この構成で開発を進めることはできますが、clientディレクトリでのnpm startはdevelopment modeでの動作な上、このままでは2つのサーバーを起動しなければいけないのでプロダクションでの使用には適しません。

プロダクション用のビルドを行うため、以下のようにpackage.jsonを変更します。

package.json
  "scripts": {
    "build": "cd client && npm run build && rm -rf ../public && mv build ../public",
    "start": "node ./bin/www"
  },

この変更を行なってnpm run buildを行うと、まずclientディレクトリ内でnpm run buildを行うことでプロダクション用のReactアプリケーションがbuildディレクトリ以下に生成され、それを親ディレクトリのpublicディレクトリとして配置することになります。こうすることで、app.js内の以下の行によってExpressサーバーがReactで書かれたフロントエンドアプリケーションを提供するようになります。

app.js
app.use(express.static(path.join(__dirname, 'public')));

Expressサーバーを再起動すると、ブラウザの8080番でアプリケーションが動作していることが確認できます。

スクリーンショット 2021-12-28 14.36.51.png

IBM Cloud Code Engineへのデプロイ

アプリケーションは完成したので、あとはこれをCode EngineへデプロイできるようにDockerfileにまとめていきます。

Dockerfile
FROM node:16 as builder

RUN mkdir /home/node/app
WORKDIR /home/node/app
COPY . .

# Run install for React app
RUN cd client && npm install
# Run install for the application (w/ Express server)
RUN npm install
# Produce production React app
RUN npm run build
# Once application is generated, client code is not needed any more
RUN rm -rf client

FROM node:16
COPY --from=builder /home/node/app /home/node/app
RUN chown -R node:node /home/node/app

USER node
WORKDIR /home/node/app

EXPOSE 8080
CMD ["node", "bin/www"]

ローカルで実験する時のために .dockerignoreも適宜指定しておくと良いと思います。

.dockerignore
Dockerfile
.dockerignore
node_modules
public
client/build
client/node_modules

ローカルでビルドして立ち上げてみます。

$ docker build . -t react-express
$ docker run -p 8080:8080 --rm react-express:latest

ブラウザからアクセスして先ほどと同じページが表示されるのを確認できたら、ソースコードをGitHubにpushしておきます。

GitHub経由でコードが取得できるようになったら、IBM CloudコンソールからCode Engineのページを開き、前回と同様にGitHubリポジトリを指定してデプロイします。手順は前回とほぼ変わりません。今回は既に8080ポートでアプリケーションが起動するのでlistenポートも空欄で大丈夫です。ビルド詳細でイメージ名等を設定したら作成をクリックして完了です。

スクリーンショット 2021-12-28 16.23.29.png

アプリケーションが作成されたら、ビルドが終わってデプロイされるのを待ちます。デプロイが完了したらブラウザからアプリケーションが動作していることが確認できます。

スクリーンショット 2021-12-28 16.10.12.png

上のdeveloper toolsを見るとわかるように、フロントエンドからバックエンドの/usersを呼び出していて、フロントエンドのアプリケーションもバックエンドのAPIも正しくExpressサーバーで提供されていることがわかります。

まとめ

Expressサーバーの構成にexpress-generator、Reactアプリケーションの作成にcreate-react-appを使い、開発環境の作成及びCode Engineへのデプロイまでの手順をまとめました。

参考

上記で使ったソースコードはこちらにあります(後の記事での変更も含んでいます): https://github.com/fterui/react-express

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?