nginx学习之编译安装篇

前言

在项目中,网关,负载均衡,反向代理等等功能都在使用 nginx。所以打算好好学习下。
本文介绍如何 mac 下编译安装 nginx

安装 openssl

我本地缺少 openssl 的最新版本,安装 nginx 会有问题。首先安装 openssl。

1. 使用 homebrew 安装最新版本

brew install openssl

2. 链接 openssl

一般情况下 mac 下会带有一个低版本的 openssl 导致 homebrew 不会自动 link,所以要强制 link。

$ brew link openssl --force
Warning: Refusing to link macOS-provided software: openssl
If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.bash_profile

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"


但是强制 link 还是会有问题,根据提示执行

echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.bash_profile

3. 检查是否安装成功

命令行输入 openssl version,有下面的输出就安装成功了


OpenSSL 1.1.1d  10 Sep 2019

下载 nginx

可以选择从官网页面下载,地址如下:
http://nginx.org/en/download.html

或者使用命令:
wget http://nginx.org/download/nginx-1.16.1.tar.gz
我们选择最新的 1.16.1 稳定版本

下载好后,我们通过命令解压

tar -xvzf nginx-1.16.1.tar.gz

编译

nginx 编译的时候有许多选项,我们需要的三个重要的外部依赖库

  1. zlib:实现 gzip 压缩解压功能
  2. pcre:实现正则表达式解析功能
  3. openssl:实现 SSL/TLS 功能
    zlib 和 pcre 都自带了,openssl 已经更新到了最新的版本,下面我们开始编译。
    在 nginx 目录下,执行下面的命令
./configure  --with-openssl=/usr/local/opt/openssl@1.1 --with-http_ssl_module // 编译前的配置检查工作
make // 编译
sudo make install // 安装编译后的可执行文件到系统中

三个命令可以分开来执行,执行完后查看输出,检查是否有问题。

问题

错误一

make 的时候出现下面的报错

/Applications/Xcode.app/Contents/Developer/usr/bin/make -f objs/Makefile
cd /usr/local/opt/openssl@1.1/openssl \
	&& if [ -f Makefile ]; then /Applications/Xcode.app/Contents/Developer/usr/bin/make clean; fi \
	&& ./config --prefix=/usr/local/opt/openssl@1.1/openssl/.openssl no-shared no-threads  \
	&& /Applications/Xcode.app/Contents/Developer/usr/bin/make \
	&& /Applications/Xcode.app/Contents/Developer/usr/bin/make install_sw LIBDIR=lib
/bin/sh: line 0: cd: /usr/local/opt/openssl@1.1/openssl: No such file or directory
make[1]: *** [/usr/local/opt/openssl@1.1/openssl/.openssl/include/openssl/ssl.h] Error 1
make: *** [build] Error 2

主要问题是 no such file or directory,但是为什么呢?
查看具体的 Makefile 文件

ALL_INCS = -I src/core \
        -I src/event \
        -I src/event/modules \
        -I src/os/unix \
        -I /usr/local/opt/openssl@1.1/.openssl/include \
        -I objs \
        -I src/http \
        -I src/http/modules

cd /usr/local/opt/openssl@1.1/
并没有.openssl 目录。需要的 ssl.h 文件在 include 目录下发现了。
解决办法:

  1. 修改 Makefile 里面的目录
  2. 创建.openssl 将 include 目录下文件拷贝过去
    我选择了方法 2
    cp -R include/ .openssl/include/

错误二

解决完上面的问题后,接着又遇到一个问题

clang: error: no such file or directory: '/usr/local/opt/openssl@1.1/.openssl/lib/libssl.a'
clang: error: no such file or directory: '/usr/local/opt/openssl@1.1/.openssl/lib/libcrypto.a'

也是找不到文件,切换到同名目录下面,顺利找到。然后把文件拷贝过去解决了。

链接

安装完成后,执行

which nginx

并没有找到文件。发现 nginx 安装到了 /usr/local/nginx/sbin 下面。
这个目录并没有在我的 PATH 路径里面。执行

echo 'export PATH="/usr/local/nginx/sbin/":"$PATH"' >> /etc/profile

把目录添加进去。

验证

1.首先启动 nginx

sudo nginx

2.查看进程是否启动

ps aux | grep nginx

我本地的输出如下

nobody           65612   0.0  0.0  2464480   2044   ??  S     6:08下午   0:00.00 nginx: worker process
root             65611   0.0  0.0  2456044    972   ??  Ss    6:08下午   0:00.00 nginx: master process nginx

3.请求 nginx

curl -vo /dev/null http://localhost/index.html

本地输出部分如下的话,就是成功响应了

* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /index.html HTTP/1.1
> Host: localhost
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.16.1
< Date: Fri, 06 Dec 2019 10:12:38 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Fri, 06 Dec 2019 09:44:20 GMT
< Connection: keep-alive
< ETag: "5dea22f4-264"
< Accept-Ranges: bytes