nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.37k stars 323 forks source link

nodejs unit-http misses `options` in createServer function #1043

Closed stefanhuber closed 7 months ago

stefanhuber commented 9 months ago

I tried to run strapi inside nginx unit. The startup of strapi doesn't work because of the following error:

TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object
    at checkListener (node:events:270:3)
    at _addListener (node:events:550:3)
    at Server.addListener (node:events:609:10)
    at new Server (/usr/local/lib/node_modules/unit-http/http_server.js:426:14)
    at Object.createServer (/usr/local/lib/node_modules/unit-http/http.js:15:12)
    at Module.createHTTPServer (/var/www/node_modules/@strapi/strapi/dist/services/server/http-server.js:16:40)
    at Module.createServer (/var/www/node_modules/@strapi/strapi/dist/services/server/index.js:26:35)
    at new Strapi (/var/www/node_modules/@strapi/strapi/dist/Strapi.js:130:27)
    at initFn (/var/www/node_modules/@strapi/strapi/dist/Strapi.js:466:18)
    at Object.<anonymous> (/var/www/index.js:2:1) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Strapi uses options with the http.createServer function as seen here in the source code. The node signature of the createServer function looks like this: http.createServer([options][, requestListener]). Looking at the http module inside the unit-http package the createServer function is missing the options argument.

Can this be solved somehow? How could strapi be started otherwise within nginx unit?

Nginx Unit has the following config.json:

{
    "listeners": {
        "*:1337": {
            "pass": "routes/main"
        }
    },
    "routes": {
        "main": [
            {
                "action": {
                    "pass": "applications/app"
                }
            }
        ]
    },
    "applications": {
        "app": {
            "type": "external",
            "working_directory": "/var/www/",
            "executable": "/usr/bin/env",
            "arguments": [
                "node",
                "--loader",
                "unit-http/loader.mjs",
                "--require",
                "unit-http/loader",
                "index.js"
            ]
        }
    }
}
stefanhuber commented 9 months ago

I could create a fix by using patch-package with the following steps:

As a current workaround this is ok. Although I think this might not be a sustainable approach. The options could be ignored in the case of our strapi deployment.

callahad commented 9 months ago

Looks like the options argument was added in Node.js v9.6.0 (2018-02-22) / v8.12.0 (2018-09-11) in https://github.com/nodejs/node/pull/15752 and we missed it when implementing our shim for http.createServer.

We should fix this in Unit, but the patch-package workaround should be fine for your use case until we can get a release out with a proper fix.