在Docker环境中编译安装Nginx
项目中用到了Nginx,作为WebServer的反向代理。所以,就想着有空看看Nginx的源码。看源码,可能就想加一下log,验证自己的理解是否正确。在自己的开发机,编译安装Nginx源码,担心会破坏了正常的业务开发环境。就想着利用Docker,把业务开发环境和自己学习环境隔离开。做了尝试之后,就有了这篇文章,总结在安装部署过程中遇到的问题,供其他需要的同学进行参考。
项目的业务开发环境是,Debian:9,使用Nginx的版本是1.10.3。为了和开发环境保持一致,Docker使用的基础镜像也是Debian:9,理所当然的,Nginx版本选择的是1.10.3。
在Debian安装Docker
准备Nginx源码
Nginx源码可以从其官网中下载
最新的稳定版本是1.18.0。因为我们项目,目前使用的是1.10.3,所以我下载的是1.10.3。
下载之后,解压缩
tar -zxvf nginx-1.10.3.tar.gz
准备Debian的镜像站文件
Debian的官方镜像源,在国内访问,速度极慢。所以,建议选用国内的镜像站。我选择的是163镜像站。新建文件sources.list,并输入如下内容:
deb http://mirrors.163.com/debian/ stretch main non-free contrib
deb http://mirrors.163.com/debian/ stretch-updates main non-free contrib
deb http://mirrors.163.com/debian/ stretch-backports main non-free contrib
deb-src http://mirrors.163.com/debian/ stretch main non-free contrib
deb-src http://mirrors.163.com/debian/ stretch-updates main non-free contrib
deb-src http://mirrors.163.com/debian/ stretch-backports main non-free contrib
deb http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib
deb-src http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib
当然,还有很多其他的镜像站,如
- 中科大镜像站
deb https://mirrors.ustc.edu.cn/debian/ stretch main contrib non-free
deb-src https://mirrors.ustc.edu.cn/debian/ stretch main contrib non-free
deb https://mirrors.ustc.edu.cn/debian/ stretch-updates main contrib non-free
deb-src https://mirrors.ustc.edu.cn/debian/ stretch-updates main contrib non-free
deb https://mirrors.ustc.edu.cn/debian/ stretch-backports main contrib non-free
deb-src https://mirrors.ustc.edu.cn/debian/ stretch-backports main contrib non-free
deb https://mirrors.ustc.edu.cn/debian-security/ stretch/updates main contrib non-free
deb-src https://mirrors.ustc.edu.cn/debian-security/ stretch/updates main contrib non-free
- 阿里云镜像站
deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb http://mirrors.aliyun.com/debian-security stretch/updates main
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main
deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
- 华为镜像站
deb https://mirrors.huaweicloud.com/debian/ stretch main contrib non-free
deb-src https://mirrors.huaweicloud.com/debian/ stretch main contrib non-free
deb https://mirrors.huaweicloud.com/debian/ stretch-updates main contrib non-free
deb-src https://mirrors.huaweicloud.com/debian/ stretch-updates main contrib non-free
deb https://mirrors.huaweicloud.com/debian/ stretch-backports main contrib non-free
deb-src https://mirrors.huaweicloud.com/debian/ stretch-backports main contrib non-free
- 清华大学镜像站
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch-updates main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch-updates main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch-backports main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ stretch-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security/ stretch/updates main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security/ stretch/updates main contrib non-free
准备Dockerfile文件
使用Docker,可以用Debian:9基础镜像启动容器,然后在容器内安装需要的软件。这么做,麻烦的是,每次新建容器,都需要按步骤重新安装一遍。
利用Dockerfile,可以直接帮我们创建需要的镜像。在启动编译好的镜像时,容器内的环境就是我们需要的,不再需要额外安装软件。
如下,是我使用的Dockerfile
FROM debian:9
COPY ./sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y wget
RUN apt-get install -y vim
RUN apt-get install -y make
# 在Docker Debian容器中安装ps,top等命令
RUN apt-get install -y procps
RUN apt-get install -y gcc
RUN apt-get install -y g++
# pcre用于解析nginx.conf中的正则表达式
RUN apt-get install -y libpcre3 libpcre3-dev
# zlib用于gzip进行压缩
RUN apt-get install -y zlib1g-dev
# OpenSSL开发库, 用于更安全的SSL协议上传输HTTP。在使用MD5、SHA1等函数时,也需要使用
RUN apt-get install -y openssl libssl-dev
RUN mkdir /nginx-1.10.3
ADD ./nginx-1.10.3 /nginx-1.10.3
编译Docker镜像
在编译前,贴一张当前工作目录的文件列表:

在Dockfile的所在目录,执行如下编译命令:
docker build --no-cache=true -f Dockfile -t nginx_src .
执行结束后,就能够看到编译完成的nginx_src镜像:

在镜像成功编译后,就可以启动容器了:
docker run -it nginx_src bash
编译安装Nginx
在容器中,我们看到Nginx源代码放在了/nginx-1.10.3目录下。cd进入该目录,并进行编译安装
# ./configure
# make
# make install
如果一切顺利,我们可以在/usr/local/nginx/sbin目录下看到nginx 可执行文件

直接执行 nginx命令,就能成功启动Nginx了。
我们可以用wget验证nginx是否启动成功:
wget 127.0.0.1:80
优化调试效率
上述操作方式,的确帮我们隔离了开发环境和自己的调试环境。但是,每次修改源码后,都需要重新编译镜像、重启容器,会引来让人失望的等待时间。尤其是那些习惯在Windows写代码的程序,每次修改后,需要同步到Debian宿主机,然后编译重启。一次简单的修改,把时间都浪费在了同步、编译镜像、重启容器的重复工作中。我们可以采取在宿主机和容器之间映射文件系统,达到宿主机文件内容和容器目录共享的目的。
为了达到共享的目的,首先我们需要修改Dockfile文件,把最后一行ADD命令删掉 ADD ./nginx-1.10.3 /nginx-1.10.3这句不再需要。
然后,我们需要修改启动容器的命令,增加-v参数。修改后的命令如下。具体路径请根据自己的情况自行修改。
docker run -v ~/docker_nginx/nginx-1.10.3:/nginx-1.10.3 -it nginx_src bash
如此,我们可以直接在宿主机修改源码,然后在容器内完成编译、安装Nginx。
对于习惯在Windows写代码的程序,可以用IDE(如CLION、VS)的远程同步功能,一键自动同步到Debian宿主机。