install unit-http on Mac OS
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
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.
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);
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.
hi @mar0x, do you have the command to build the unit with ssl support? ..
You may try to:
- disable deprecations with
-Wno-deprecated-declarationsCFLAG 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 fornpm install unit-httpeither local or global.
... the
--localwill not be taken into account, look: ...
Could you please provide complete list of executed commands (it is hard to guess what was wrong).
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
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.
@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.
.. 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
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?
... 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, please see this repo: build-nginx-unit. Your help is greatly appreciated
@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
I ended up running inside a docker container. I think this should be suggested in the docs for Mac users
Hi @haikyuu , are you using Apple silicon? (M1/M2)
@lcrilly yes