41
41

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.

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

Last updated at Posted at 2018-02-23

はじめに

今更ながら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.</h1>
       <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分でできましたか...?
もし少しあふれてしまっていたら申し訳ありません。誇張したタイトルでした。
しかし、フルスクラッチするよりかなり簡単だったのではないでしょうか。
環境構築で消耗しないでコンテンツやサービスに注力したいですね。

41
41
1

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
41
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?