Nuxt + Express + Nginx with Docker 作成

目的

Nginx, Nuxt, Express を用いたDocker環境を作成した。 Nginxを用いる理由は、アクセスログをnginxにやらせたかったからで必須ではないです。 envoy?的なイメージ。

設定関連

Nginx

unix socketでExpressと通信をするようにする。 ポートでも問題ないけど、試して見たかったのでunix socket を利用してみた。

nginx.confこんな感じ。

upstream nuxt_app {
  server unix:/app/tmp/nuxt.sock;
}

server {
  listen 80;
  server_name ${SERVER_NAME};

  access_log stdout;
  error_log  stderr warn;
  access_log /app/log/access.log tsv;
  error_log  /app/log/error.log warn;

  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass http://nuxt_app;
  }
}

Nuxt & Express

app/tmp をvolume マウントして、Nginxから見られるようにすることで、unix socketによる通信を可能にしてます。 DockerFileはこんな感じ。

FROM node:11.8.0-alpine
ENV LANG C.UTF-8

RUN mkdir /app
WORKDIR /app

ADD . /app

VOLUME /app/tmp

RUN npm i -g yarn
RUN yarn install --production

ARG ENV
RUN yarn nuxt build
CMD node server/index.js

チュートリアル通り、nuxtをセットアップして、server.js をunix port でlistenするようにする。 EC2だと、pm2使ってたが、dockerだとなくていいらしいので楽!

参考

Node.jsをunix domain socketでlistenしたときにNginxからプロキシできない - なっく日報

async function start() {
  ...省略
  app.use(nuxt.render);

  // Listen the server
  const socketPath = '/app/tmp/nuxt.sock';
  // 必要ならここで既にsockファイルが存在する場合削除が必要かも。
  app.listen(socketPath, (err) => {
    if (err) throw err;
    fs.chmodSync(socketPath, 660);
    consola.ready({
      message: `Listening on socket`,
      badge: true
    });
  }
}
start();

docker-compose

こんな感じ。

version: '2'
services:
  app:
    build:
      context: .
      args:
        ENV: ${ENV}
    env_file:
    - .env

  nginx:
    build: nginx
    ports:
    - "80:80"
    volumes_from:
    - app
    env_file:
    - .env
    depends_on:
    - app