unit icon indicating copy to clipboard operation
unit copied to clipboard

install unit-http on Mac OS

Open Dmitry-N-Medvedev opened this issue 6 years ago • 16 comments

Mac OS: 10.15.3 (19D76)
NodeJS: v13.9.0
npm: 6.13.7

hi,

I'm trying to install the unit-http on Mac OS:

npm install unit-http --global --unsafe-permk

which results in:

> [email protected] install /Users/dmitrymedvedev/.nvm/versions/node/13.9.0/lib/node_modules/unit-http
> node-gyp configure build

  CXX(target) Release/obj.target/unit-http/unit.o
In file included from ../unit.cpp:6:
In file included from ../unit.h:9:
../nxt_napi.h:17:10: fatal error: 'nxt_unit.h' file not found
#include <nxt_unit.h>
         ^~~~~~~~~~~~
1 error generated.
make: *** [Release/obj.target/unit-http/unit.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:321:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Darwin 19.3.0
gyp ERR! command "/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/bin/node" "/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build"
gyp ERR! cwd /Users/dmitrymedvedev/.nvm/versions/node/13.9.0/lib/node_modules/unit-http
gyp ERR! node -v v13.9.0
gyp ERR! node-gyp -v v5.0.7
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp configure build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/dmitrymedvedev/.npm/_logs/2020-02-19T00_50_52_264Z-debug.log

The question is: is the unit-http not compatible with Mac? If that is not the case, could you please point me to a proper installation procedure?

Regards, Dmitry

Dmitry-N-Medvedev avatar Feb 19 '20 01:02 Dmitry-N-Medvedev

Hello,

Node.js module unit-http can be used on Mac OS.

Unit header files and library required to build module. For Mac OS you need to configure and build Unit and library from sources (you need Unit to run your app anyway).

Node.js module can be configured and installed from this source tree:

./configure nodejs
make node-install

There is an option to install unit-http locally to your project.

mar0x avatar Feb 19 '20 07:02 mar0x

hi @mar0x, do you have the command to build the unit with ssl support?

I do this:

./configure \
  --openssl \
  --cc-opt=-I$OPENSSL_DIR \
  --ld-opt=-L$OPENSSL_DIR \
  --prefix=$NGINX_UNIT_PREFIX

make && make install

and get errors about functions in ssl marked as deprecated like this:

src/nxt_openssl.c:1047:15: error: 'ERR_get_error_line_data' is deprecated [-Werror,-Wdeprecated-declarations]
        err = ERR_get_error_line_data(NULL, NULL, &data, &flags);

Dmitry-N-Medvedev avatar Feb 20 '20 20:02 Dmitry-N-Medvedev

in the following snippet:

./configure nodejs \
  --local=$NGINX_UNIT_PREFIX/module

make node-local-install

the --local will not be taken into account, look:

  "dependencies": {
    "unit-http": "file:distros/unit/build/node-unit-http.tar.gz"
  }

NB: the distros is the directory for both openssl and unit sources. The node-local-install should have the module installed in the $NGINX_UNIT_PREFIX/module path instead.

Dmitry-N-Medvedev avatar Feb 20 '20 22:02 Dmitry-N-Medvedev

hi @mar0x, do you have the command to build the unit with ssl support? ..

You may try to:

  • disable deprecations with -Wno-deprecated-declarations CFLAG or
  • build your own openssl manually or
  • use openssl from MacPorts or
  • use brew and install unit from my tap with command brew install mar0x/unit/unit, this makes unit header files and library available for npm install unit-http either local or global.

mar0x avatar Feb 20 '20 22:02 mar0x

... the --local will not be taken into account, look: ...

Could you please provide complete list of executed commands (it is hard to guess what was wrong).

mar0x avatar Feb 20 '20 22:02 mar0x

hi @mar0x, please see the files I am using to build both the unit and the unit-http lib.

env.sh

#!/bin/bash

export CWD=$(pwd)

# export ADV_BUILD_DIR=$(mktemp -d)
mkdir -p "$CWD/distros"

export ADV_BUILD_DIR="$CWD/distros"
export OPENSSL_DIR="$ADV_BUILD_DIR/openssl"

export NGINX_UNIT_DIR="$ADV_BUILD_DIR/unit"
export NGINX_UNIT_PREFIX="$CWD/usr/local/unit"

export OPENSSL_GIT=https://github.com/openssl/openssl.git
export UNIT_GIT=https://github.com/nginx/unit

nginx-unit.sh

#!/bin/bash

source ./scripts/install/env.sh

NODE_UNIT_TGZ="$NGINX_UNIT_DIR/build/node-unit-http.tar.gz"

pnpm add node-gyp --global --unsafe-perm

if [[ ! -d  $NGINX_UNIT_DIR ]]
then
  echo "downloading NGINX-UNIT"

  mkdir -p $NGINX_UNIT_DIR

  cd $NGINX_UNIT_DIR

  git clone $UNIT_GIT .
else
  echo "updating NGINX-UNIT"

  cd $NGINX_UNIT_DIR

  git pull

  make clean
fi

./configure \
  --prefix=$NGINX_UNIT_PREFIX \
  --openssl \
  --cc-opt="-Wno-deprecated-declarations -I$OPENSSL_DIR"

echo "install NGINX-UNIT"
make && make install

./configure nodejs \
  --local=$NGINX_UNIT_PREFIX/module \
  --node-gyp=$(dirname $(dirname $(which node)))/lib/node_modules/npm/bin/node-gyp-bin/node-gyp

echo "install unit-http lib"
make node-install
mkdir $NGINX_UNIT_PREFIX/module
cp $NGINX_UNIT_DIR/build/node-unit-http.tar.gz $NGINX_UNIT_PREFIX/module

Dmitry-N-Medvedev avatar Feb 21 '20 22:02 Dmitry-N-Medvedev

one more problem: the node-unit-http.tar.gz file does not contain a *.node library and when installed locally ( when there is a devDependencies generated for it in the package.json file ) cannot be installed with npm install command.

Dmitry-N-Medvedev avatar Feb 21 '20 22:02 Dmitry-N-Medvedev

@mar0x,

using something like brew install mar0x/unit/unit is not an option since I need to be able to build the unit and the unit-http library and have complete control over them, e.g.: the unit will be invoked in a test environment as a separate process from a test script.

These two will also be distributed by a couple of other projects. So, the point is: complete control is required.

Dmitry-N-Medvedev avatar Feb 21 '20 22:02 Dmitry-N-Medvedev

.. the node-unit-http.tar.gz file does not contain a *.node library ...

Yes, it contains only sources and can be used in npm install.

.. cannot be installed with npm install command.

You can install node module with npm install after you add extra variables to your environment:

export UNIT_SRC_PATH=$NGINX_UNIT_DIR/src
export UNIT_BUILD_PATH=$NGINX_UNIT_DIR/build
export UNIT_LIB_STATIC_PATH=$NGINX_UNIT_DIR/build/libunit.a
npm install $NGINX_UNIT_DIR/build/build/node-unit-http.tar.gz

mar0x avatar Feb 22 '20 22:02 mar0x

hi @mar0x ,

the thing is: if I want to install the node module I will have to have all the sources on the target machine. Right?

what I want to achieve on the other hand, is that I establish a build routing for each OS, run the build, get the installable package for each OS used ( actuall for Mac OS and Debian ) and distribute this package among all the developers so that they are not required to rebuild it all from scratch.

Does it make sense? Is it feasible?

Dmitry-N-Medvedev avatar Feb 23 '20 12:02 Dmitry-N-Medvedev

... have all the sources on the target machine ...

Not all sources, only 10 header files and 1 static library required to build module.

Does it make sense?

Definitely, yes.

Is it feasible?

I have no idea how to properly package binary library for Node.js module. People wants to use npm install smoothly on all platforms and only way to achieve this (as far as I know) is to distribute sources and build binary on the target host.

On Debian developers may install unit-dev and then npm install unit-http should work (yes, there will be compilation during install). On macOS there is no standard package manager and using brew is not an option for you.

We have similar situation with Go module and we are trying to support traditional ways to install modules for Go and Node.js. Please let me know if you see a more convenient/correct/smooth solution.

mar0x avatar Feb 25 '20 07:02 mar0x

@mar0x, please see this repo: build-nginx-unit. Your help is greatly appreciated

Dmitry-N-Medvedev avatar Mar 14 '20 21:03 Dmitry-N-Medvedev

@mar0x Thanks for your help. But it's not really clear from reading the docs, and also reading through this issue how to actually install unit-http on a Mac.

It would be great to add detailed instructions to the docs as people who want to evaluate nginx unit will definitely be thrown away by how hard it is to make it work in Mac.

Even after a successful install, I get this error

2023/09/26 11:38:49 [alert] 39189#39732944 [unit] NXT_UNIT_INIT is not in the current environment
/Users/abdellah/workspace/s/radix3/node_modules/.pnpm/file+..+unit+build+node-unit-http.tar.gz/node_modules/unit-http/http_server.js:406
    this.unit.createServer();
              ^

Error: Failed to create Unit object
    at new Server

haikyuu avatar Sep 26 '23 08:09 haikyuu

I ended up running inside a docker container. I think this should be suggested in the docs for Mac users

haikyuu avatar Sep 26 '23 08:09 haikyuu

Hi @haikyuu , are you using Apple silicon? (M1/M2)

lcrilly avatar Sep 26 '23 10:09 lcrilly

@lcrilly yes

haikyuu avatar Sep 26 '23 11:09 haikyuu