Edited at

10分で作るNext.jsとDockerを使ったSSR+SPA環境

More than 1 year has passed since last update.


はじめに

今更ながらNext.jsを触ったところ、とても便利でした。

手っ取り早くdocker-compose upで動かせるところまでを記載します。


前提

以下の環境が整っているものとします。


  • Node.jsのstableバージョンがインストールされている

  • Dockerがインストールされている


ワークスペースの作成

ディレクトリを作成します。

※yarnで書いてますがnpmでも問題ありません

$ mkdir next-docker // 名前は任意で

$ cd next-docker
$ yarn init --yes

今回は最小構成で必要なモジュールをインストールします。

$ yarn add next react react-dom -S


/pagesディレクトリの作成・コンポーネントの編集

next.js/pagesに存在するファイルを見てルーティングを行います。

/pagesの中にIndex.jsAbout.jsを作成します。

$ mkdir pages

$ cd pages
$ touch Index.js About.js


Files

/pages

- Index.js
- About.js
...

Index.jsAbout.jsは以下のように書きます。

Index.jsではgetInitialProps()を使用してサーバーサイドとクライアントサイドどちらでレンダリングされたのかをisServerプロパティでわかるようにしています。

Linkコンポーネントはnext.jsが提供しているもので、SPAとしてブラウザの履歴を含めたページ遷移を実行してくれる大変便利なラッパーコンポーネントです。


./pages/index.js

import Link from 'next/link';

const Index = (props) => (
<div>
<h1>Index page.</h1>
<p>This page was rendered on the server side: {props.isServer.toString()}</p>
<Link href="/about">
<a>About</a>
</Link>
</div>
);

Index.getInitialProps = async function () {
return {
isServer: typeof window === 'undefined'
}
};

export default Index;



./pages/about.js

import Link from 'next/link';

export default () => (
<div>
<h1>About page.</p>
<Link href="/">
<a>HOME</a>
</Link>
</div>
);



表示確認

package.jsonにはscriptsを書いておきます。


package.json

  "scripts": {

"dev": "next",
"build": "next build",
"start": "next start"
},
...

実際に実行してみましょう。

(ターミナルはプロジェクトのルートに戻しておいてください

$ yarn run dev

ローカルサーバーが立ち上がりますので、http://localhost:3000にアクセスします。

無事にページが表示されていたら成功です。

ページ遷移もためしてエラーがなければ次に進みましょう。


docker-compose

サンプルアプリケーションはできたため、実行環境をdockerで作ります。

ctrl + cなどしてnext.jsで立てたサーバーは一度ストップしておいてください。

docker-compose.ymlを作ります。

$ touch docker-compose.yml

作成したファイルを開いて以下のように編集します。

今回書き方は割愛しますが、nginxでwebサーバーを立ててnext.jsで立てたアプリケーションサーバーにリバースプロキシで接続します。


docker-compose.yml

version: '2'

services:
nginx:
image: nginx:stable
container_name: nginx
ports:
- "80:80"
volumes:
- "./conf.d:/etc/nginx/conf.d"
links:
- express

express:
image: node:8.9.0-alpine
container_name: express
hostname: express
volumes:
- ".:/src"
working_dir: /src
command: [sh, -c, npm install && npm run build && npm run start]
ports:
- "3000:3000"


nginxの設定ファイルを作成します。

$ mkdir conf.d

$ cd conf.d
$ touch default.conf

nginxも最小構成で書きます。


default.conf

server {

listen 80;
server_name localhost;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://express:3000/;
}
}


表示確認

docker-composeでコンテナを起動します。

$ docker-compose up

少し待つとnext.jsのサーバーが起動したことが分かるかと思います。

http:localhost/にアクセスしましょう。nginxにアクセスするためポートは不要です。

同じようにページが表示されていれば成功です。

トップページのテキストThis page was rendered on the server side:の箇所に注目してください。ページ遷移したときと、ブラウザでリロードなどをしたときでtruefalseに切り替わっているのが分かるかと思います。

簡単ですね!!

isomorphicなアプリケーションが既にできています...!!


おわりに

10分でできましたか...?

もし少しあふれてしまっていたら申し訳ありません。誇張したタイトルでした。

しかし、フルスクラッチするよりかなり簡単だったのではないでしょうか。

環境構築で消耗しないでコンテンツやサービスに注力したいですね。