欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

本文是《Docker下的OpenResty三部曲》的第二章,在前文《Docker下的OpenResty三部曲之一:极速体验》我们简单的体验了Nginx+Lua提供的web服务,但是并没有深入开发细节,今天就来一起实战这个镜像的制作过程;

实战环境

操作系统:Ubuntu16;
Docker版本:17.03.2-ce;

步骤列举

此镜像的准备工作如下:

  1. 提前下载必要的资源:ngx_openresty、ngx_cache_purge、nginx_upstream_check_module;
  2. 定制nginx.conf;
  3. 开发用于demo演示的配置文件和lua脚本;

镜像的Dockerfile脚本中要做以下事情:

  1. 源镜像为Ubuntu 16;
  2. 准备两个目录:nginx工作目录/usr/servers,lua脚本的存放目录/usr/local/work
  3. apt换源,用阿里云的源;
  4. apt更新;
  5. 安装必要的应用,如gcc、libreadline-dev等;
  6. 安装ngx_cache_purge、nginx_upstream_check_module、ngx_openresty;
  7. 将定制好的nginx.conf放入镜像;
  8. 将用于demo演示的配置文件和lua脚本放入镜像;
  9. 暴露80端口;
  10. 配置容器启动命令,启动nginx;

准备材料

本次构建镜像所需的材料我已准备齐全,您可以在github下载到:

名称链接备注
项目主页https://github.com/zq2599/blog_download_files该项目在GitHub上的主页
git仓库地址(https)https://github.com/zq2599/blog_download_files.git该项目源码的仓库地址,https协议
git仓库地址(ssh)git@github.com:zq2599/blog_download_files.git该项目源码的仓库地址,ssh协议

这个git项目中有多个目录,本次所需的资源放在nginx_lua_docker_image_files,如下图红框所示:

在这里插入图片描述

Dockerfile文件

下载了上述所有材料后,我们就可以进行构建了,Dockerfile也在上述材料中,内容如下,将我们前面列举的工作逐个完成:

# Docker image for OpenResty study
# VERSION 0.0.1
# Author: bolingcavalry

#基础镜像使用ubuntu:16.04
FROM ubuntu:16.04

#作者
MAINTAINER BolingCavalry <zq2599@gmail.com>

#定义工作目录
ENV WORK_PATH /usr/local/work

#定义安装目录
ENV INSTALL_PATH /usr/servers

#定义nginx-openresty文件夹名称
ENV NGX_OPENRESTY_PACKAGE_NAME ngx_openresty-1.7.7.2

#定义ngx_cache_purge文件夹名称,该模块用于清理nginx缓存
ENV NGX_CACHE_PURGE_PACKAGE_NAME ngx_cache_purge-2.3

#定义nginx_upstream_check_module文件夹名称,该模块用于ustream健康检查
ENV NGX_UPSTREAM_CHECK_PACKAGE_NAME nginx_upstream_check_module-0.3.0

#创建工作目录
RUN mkdir -p $WORK_PATH

#创建安装目录
RUN mkdir -p $INSTALL_PATH

#apt换源,用阿里云的源,删除原有的源
RUN rm /etc/apt/sources.list

#apt换源,用阿里云的源,复制新的源
COPY ./sources.list /etc/apt/sources.list

#apt更新
RUN apt-get update

#创建安装目录
RUN apt-get install -y make gcc libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl 

#把nginx-openresty文件夹复制到工作目录
COPY ./$NGX_OPENRESTY_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME

######luajit start######
#进入make目录,执行编译luajit
RUN cd $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/LuaJIT-2.1-20150120/ && make clean && make && make install

#软连接
RUN ln -sf luajit-2.1.0-alpha /usr/local/bin/luajit
######luajit end######


######module start######
#把ngx_cache_purge文件夹复制到工作目录
COPY ./$NGX_CACHE_PURGE_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/$NGX_CACHE_PURGE_PACKAGE_NAME

#把nginx_upstream_check_module文件夹复制到工作目录
COPY ./$NGX_UPSTREAM_CHECK_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/$NGX_UPSTREAM_CHECK_PACKAGE_NAME
######module end######


######ngx_openresty start######
#进入ngx_openresty目录,执行configure,执行构建
RUN cd $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME && ./configure --prefix=$INSTALL_PATH --with-http_realip_module  --with-pcre  --with-luajit --add-module=./bundle/$NGX_CACHE_PURGE_PACKAGE_NAME/ --add-module=./bundle/$NGX_UPSTREAM_CHECK_PACKAGE_NAME/ -j2 && make && make install  
######ngx_openresty end######


######复制配置文件 start######
#删除原有的nginx.conf
RUN rm $INSTALL_PATH/nginx/conf/nginx.conf
#用定制的nginx.conf
COPY ./nginx.conf $INSTALL_PATH/nginx/conf/ 
#将新的conf文件放入指定位置,nginx.conf中对此文件有include
COPY ./boling_cavalry.conf $WORK_PATH/
#创建放置lua库的目录
RUN mkdir $WORK_PATH/lualib
#复制一个lua库文件
COPY ./sequare.lua $WORK_PATH/lualib
#创建放置lua脚本的目录
RUN mkdir $WORK_PATH/lua
#复制一个lua的demo脚本
COPY ./test_request.lua $WORK_PATH/lua
COPY ./get_sequare.lua $WORK_PATH/lua
######复制配置文件 end######


#暴露8080端口
EXPOSE 80

#启动NGINX
CMD ["/usr/servers/nginx/sbin/nginx", "-g", "daemon off;"]

以上脚本都有注释,就不再赘述太多了,有几个关键点需要注意:

  1. Nginx和OpenResty等安装在/usr/servers目录,而我们实战的时候配置的conf文件以及编写的lua脚本都存放在/usr/local/work目录;
  2. 记得安装make、gcc等工具,否则无法编译构建Nginx;
  3. 虽然/usr/servers/nginx/sbin/nginx可以启动nginx,但是会在后台运行,在docker容器中如果最后一个启动的进程不再占有终端,docker服务就会停止该容器,所以需要添加"-g daemon off"参数,使得nginx进程不要以后台服务的方式运行,这样容器就不会退出了;

定制的nginx.conf

从Dockerfile中我们看见原有的nginx.conf被我们定制的同名文件替换了,新的nginx.conf相比而言做了以下改动:

  • 添加自定义模块所在目录:
lua_package_path "/usr/local/work/lualib/?.lua;;";  #lua 模块  
lua_package_cpath "/usr/local/work/lualib/?.so;;";  #c模块
  • 添加自定义配置文件:
include /usr/local/work/boling_cavalry.conf;

自定义配置文件boling_cavalry.conf

我们将lua相关实战的配置都放在boling_cavalry.conf,避免频繁修改nginx.conf:

server {  
    listen       80;  
    server_name  _;  
  
    location ~ /lua_request/(\d+)/(\d+) {  
        #设置nginx变量  
        set $a $1;   
        set $b $host;  
        default_type "text/html";  
        #nginx内容处理  
        content_by_lua_file /usr/local/work/lua/test_request.lua;  
        #内容体处理完成后调用  
        echo_after_body "ngx.var.b $b";  
    }  

    
    location ~ /lua_sequare/(\d+)/(\d+) {
        set $a $1;
        set $b $2;
        default_type "text/html";
        set_by_lua_file $num /usr/local/work/lua/get_sequare.lua;
	echo "长 : $a , 宽 : $b , 面积 : $num";
    }
}

如上所示,定义了两个二级域名的入口逻辑:lua_request和lua_sequare,lua_request用content_by_lua_file命令委托test_request.lua生成页面内容,lua_sequare用set_by_lua_file给num变量赋值;

脚本test_request.lua

这个脚本里是一些常用的OpenResty的API示例,来自开涛大神的文章《第二章 OpenResty(Nginx+Lua)开发入门》

脚本get_sequare.lua

这个脚本演示了如何使用自定义module,有个根据长和宽计算长方形面积的module:sequare.lua,如下所示:

-- square.lua 长方形模块
local _M = {}           -- 局部的变量
_M._VERSION = '1.0'     -- 模块版本

local mt = { __index = _M }

function _M.new(self, width, height)
    return setmetatable({ width=width, height=height }, mt)
end

function _M.get_square(self)
    return self.width * self.height
end

function _M.get_circumference(self)
    return (self.width + self.height) * 2
end

return _M

square可以接收长和宽两个参数,然后返回计算结果,调用该module的代码在get_sequare.lua,如下:

local var = ngx.var
local i = var.a
local j = var.b
local sequare = require("sequare")
local s1 = sequare:new(i, j)

return s1:get_square() 

如上所示,接收boling_cavalry.conf中的配置传来的长和宽两个参数,调用sequare计算,返回结果;

构建镜像

将上述材料全部准备完毕后,在Dockerfile文件所在目录执行以下命令即可构建Docker镜像:

docker build -t bolingcavalry/ubuntu16-openresty:0.0.1 .

输出信息如下:

root@lua:~/work# docker build -t bolingcavalry/ubuntu16-openresty:0.0.1 .
Sending build context to Docker daemon 24.14 MB
Step 1/29 : FROM ubuntu:16.04
 ---> 0458a4468cbc
Step 2/29 : MAINTAINER BolingCavalry <zq2599@gmail.com>
 ---> Using cache
 ---> 16f3fb4a718e
Step 3/29 : ENV WORK_PATH /usr/local/work
 ---> Using cache
 ---> 921914bc99f0
Step 4/29 : ENV INSTALL_PATH /usr/servers
 ---> Using cache
 ---> d9b43a681758
Step 5/29 : ENV NGX_OPENRESTY_PACKAGE_NAME ngx_openresty-1.7.7.2
 ---> Using cache
 ---> 54b1aa1a7185
Step 6/29 : ENV NGX_CACHE_PURGE_PACKAGE_NAME ngx_cache_purge-2.3
 ---> Using cache
 ---> de9f34f26719
Step 7/29 : ENV NGX_UPSTREAM_CHECK_PACKAGE_NAME nginx_upstream_check_module-0.3.0
 ---> Using cache
 ---> 343a711f2ec7
Step 8/29 : RUN mkdir -p $WORK_PATH
 ---> Using cache
 ---> 7737165f680e
Step 9/29 : RUN mkdir -p $INSTALL_PATH
 ---> Using cache
 ---> f11bbb0c557d
Step 10/29 : RUN rm /etc/apt/sources.list
 ---> Using cache
 ---> 862747a9c96f
Step 11/29 : COPY ./sources.list /etc/apt/sources.list
 ---> Using cache
 ---> 3ca0839fc2ec
Step 12/29 : RUN apt-get update
 ---> Using cache
 ---> 81f808e0748b
Step 13/29 : RUN apt-get install -y make gcc libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl
 ---> Using cache
 ---> f4b9ff74e25d
Step 14/29 : COPY ./$NGX_OPENRESTY_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME
 ---> Using cache
 ---> 6877069f83e7
Step 15/29 : RUN cd $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/LuaJIT-2.1-20150120/ && make clean && make && make install
 ---> Using cache
 ---> b2a7f42a08b6
Step 16/29 : RUN ln -sf luajit-2.1.0-alpha /usr/local/bin/luajit
 ---> Using cache
 ---> c5cf9ba881aa
Step 17/29 : COPY ./$NGX_CACHE_PURGE_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/$NGX_CACHE_PURGE_PACKAGE_NAME
 ---> Using cache
 ---> c49c78734c6d
Step 18/29 : COPY ./$NGX_UPSTREAM_CHECK_PACKAGE_NAME $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME/bundle/$NGX_UPSTREAM_CHECK_PACKAGE_NAME
 ---> Using cache
 ---> b2257e5816d1
Step 19/29 : RUN cd $INSTALL_PATH/$NGX_OPENRESTY_PACKAGE_NAME && ./configure --prefix=$INSTALL_PATH --with-http_realip_module  --with-pcre  --with-luajit --add-module=./bundle/$NGX_CACHE_PURGE_PACKAGE_NAME/ --add-module=./bundle/$NGX_UPSTREAM_CHECK_PACKAGE_NAME/ -j2 && make && make install
 ---> Using cache
 ---> 84959b5d75d4
Step 20/29 : RUN rm $INSTALL_PATH/nginx/conf/nginx.conf
 ---> Using cache
 ---> 23c01dded8c4
Step 21/29 : COPY ./nginx.conf $INSTALL_PATH/nginx/conf/
 ---> Using cache
 ---> 776be05466ac
Step 22/29 : COPY ./boling_cavalry.conf $WORK_PATH/
 ---> 4aa8b7334045
Removing intermediate container f7e28f9fefba
Step 23/29 : RUN mkdir $WORK_PATH/lualib
 ---> Running in 053c920c4881
 ---> 90a35711cb82
Removing intermediate container 053c920c4881
Step 24/29 : COPY ./sequare.lua $WORK_PATH/lualib
 ---> 7d5ddc4a2896
Removing intermediate container ab8f06369aaa
Step 25/29 : RUN mkdir $WORK_PATH/lua
 ---> Running in 82739117102b
 ---> 440da8a1d071
Removing intermediate container 82739117102b
Step 26/29 : COPY ./test_request.lua $WORK_PATH/lua
 ---> adbce564c888
Removing intermediate container 1814b85953a4
Step 27/29 : COPY ./get_sequare.lua $WORK_PATH/lua
 ---> 7dd1d9c25b56
Removing intermediate container d7f97d15993a
Step 28/29 : EXPOSE 80
 ---> Running in 236bf062b73c
 ---> 3df5b6bbf8e7
Removing intermediate container 236bf062b73c
Step 29/29 : CMD /usr/servers/nginx/sbin/nginx -g daemon off;
 ---> Running in 20e3d9ce31de
 ---> 98b44edabb60
Removing intermediate container 20e3d9ce31de
Successfully built 98b44edabb60

实战OpenResty

镜像构建成功后,就可以像上一章那样运行和体验Nginx+Lua服务了,您也可以在容器中自己去修改或者添加Lua脚本,实现更多的功能,修改完毕conf或者Lua脚本后,记得执行以下两个命令:

  1. 测试Nginx配置:/usr/servers/nginx/sbin/nginx -t
  2. Nginx重新加载配置:/usr/servers/nginx/sbin/nginx -c /usr/servers/nginx/conf/nginx.conf -s reload

至此,整个镜像的制作过程就完成了,接下来的章节,我们去kubernetes实战,搭建Nginx+Lua+Tomcat的综合服务;

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢迎关注公众号:程序员欣宸

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界…

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐