NGINX UNITでgraphql MSAサーバーを作って見ました。

nginxはウェブ・サービスでよく使われる万能ですが、nginx-unitはよく知られてないみたいです。

Nginx-unitはMSAのために誕生したらしいです。これはnginx-unitのHPを見るとすぐ分かります。

https://www.nginx.com/products/nginx-unit/

![](https://www.nginx.com/wp-content/uploads/2020/11/dia-FM-2020-11-11-what-is-nginx-unit-05-1024x725-padding.svg)

このイメージを見たらMSAような構造でしょうね！

docker nginx-unitを基準でnginx-unitはnginxより設定をよく簡単にさせたり、動的にconfigを変更できます。性能もhttp connectionを１００００くらいまでカーバできるそうです。設定はconfig.jsonを調整すればOKです（この部分が一番気に入った）。

Node expressで作ったgraphqlサーバをMSAにする過程を述べます。

例えはGraphQL公式HPのexpressサーバのコードを参照しました。詳しいのは
https://graphql.org/graphql-js/running-an-express-graphql-server/　
を参考してください。HPとの違うのはファイル名はindex.jsじゃなくapp.jsでしたことです。

```javascript
//app.js
var express = require('express');
var { graphqlHTTP } = require('express-graphql');
var { buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
  type Query {
    hello: String
    amount: Int
  }
`);

// The root provides a resolver function for each API endpoint
var root = {
  hello: () => 'Hello, Hello, Hello',
  amount:() => 34500
};

var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');
```



これは4000番ポートを使って/graphqlでサービスします。

次はconfig.jsonを用意します。以下はexpress用config.jsです。

```json
{
    "listeners": {
        "*:4000": {
            "pass": "applications/express"
        }
    },

    "applications": {
        "express": {
            "type": "external",
            "working_directory": "/www/",
            "executable": "/usr/bin/env",
            "arguments": [
                "node",
                "--loader",
                "unit-http/loader.mjs",
                "--require",
                "unit-http/loader",
                "app.js"
            ]
        }
    }
}
```

`listeners`でポート4000で変更して`applications`を見るとworking directoryが`/www`であるのを分かります。このディレクトリでapp.jsをコピーします。

docker image はDockerfileを用いたdocker buildコマンドで作ります。Dockerfileは以下のように構成します。

```
# Using base image provided by nginx unit

# nginx unit node16のバージョンimageを選択(1.26.1-node16)
FROM nginx/unit:1.26.1-node16

# docker imageの中/docker-entrypoint.d/で存在るconfig.jsonを作業したconfig.jsonで切り替え。
COPY config.json /docker-entrypoint.d/config.json

# expressのapp.jsをdocker imageの中/www/にコピー。もし他の必要なライブラリがあれば一緒にコピー。
COPY app.js /www/

# docker imageの中でgraphQLのためにexpress, express-graphql, graphqlインストール
RUN cd /www && npm install express express-graphql graphql --save

# docker imageの中でExpressのためにunit-httpインストール
RUN cd /www && npm install -g --unsafe-perm unit-http
RUN cd /www && npm link unit-http

# 使用するポートexpose
EXPOSE 4000
```

ここにはgraphqlのみ設置するんですが他の必要なのがあれば`RUN cd /www && npm install 必要なもの`で追加します。

現在dockerでbuildするディレクトリの内部は以下のようです。

```
.
├── Dockerfile
├── app.js
├── config.json
├── node_modules ⇦ フォルダです。
├── package-lock.json
└── package.json
```



このディレクトリで`docker build`をします。

```
> docker build --tag=expressql .
```

Docker buildが終わると`docker images`で結果を確認。

```
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
expressql    latest    541b254c0f04   3 hours ago    929MB ⇦ これです。
jenkins      1.0       35ec6519bffc   4 months ago   1.18GB
```

私は予め3時間前に作業したので'3 hours ago'で表示されてまね。



さ、コンテイナーを立ち上げましょう。

```
docker run -d -p 4000:4000 --name eql expressql
```

http://localhost:4000/graphql で接続すると以下のような画面が出ると成功！。

![](https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2022/image-20220211182216889.png)



それでnginx-unitを用いた簡単なMSAアプリケーションを作って見ました。