Docker容器配置Nginx实例分享

作为目前最火的应用,Docker 确实存在着其独到之处,无论是程序猿还是运维都应该听说过 Docker 的大名,Docker 已经走过了许多的坑,目前最新版本是 v1.11.0 版本,应该说是完全能承载开发使用和运维监控,这款工具能帮助我们高效的打包、发布和运行承载着应用程序的容器系统。而且收集日志、帮助 App 的快速开发都有很大作用。

容器和虚拟机,经常是被拿出来对比的两款产品,实际上两者有着根本的差别,虚拟机是完全模拟了一台真实计算机,在上面运行的系统可能或者不可能知道自己运行在虚拟化环境下,并且虚拟机承载了将用户指令转换为特权指令的功能,所以虚拟机非常复杂,但是很完备,而 Docker 则完全不同。Docker 使用主机自身的 Linux 内核,然后从镜像中产生磁盘目录和软件,所有的进程都运行在主机上,如果有兴趣的话完全可以 ps aux 查询一下,就能发现在 Docker 中运行的进程,只不过 Docker 对其做了如同 chroot 差不多概念的封装。

Docker 真正用法

在 Docker 发展的早期,由于 busybox 等轻量化镜像不完备,所以各大发行版的缩减瘦身镜像得到了更多的使用,特别是由于 Docker 本身是在 Ubuntu 环境下开发的,所以 Ubuntu 和 Debian 在很多镜像中作为基镜像,以此作为基础产生目标镜像。但是随着在实践中的使用,其弊端也暴露出来了,就是太过于重量化,比如 systemd 的日志功能和 Docker 本身的日志功能被重复使用,镜像很难缩小到 300M 以内。而且 Docker 的推荐使用方式就是单进程模型,而并非是多个进程如同一个完备的操作系统一般。所以就产生了 alpine 等轻量级基镜像,alpine 是什么则可以自行百度,这个镜像是 Docker 官方推荐的镜像,未来官方镜像将会迁移到 alpine 作为基础的镜像上,所以,我们应当早日熟悉此镜像。

构建 Dockerfile

本文讲述的是 Docker 容器的 Nginx 实践,不过官方实际上已经有了关于 Nginx 的 alpine 镜像。而在实际使用过程中,笔者更多的是使用 Tengine,所以根据官方 Dockerfile 的参考,笔者自行编写了 Tengine 镜像的 Dockerfile,希望能抛砖引玉,各位能够批评指正。

FROM alpine:3.3
MAINTAINER ChasonTang <chasontang@gmail.com>

ENV TENGINE_VERSION 2.1.2
ENV CONFIG "\
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --http-client-body-temp-path=/var/cache/nginx/client_temp \
    --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
    --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
    --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_auth_request_module \
    --with-mail \
    --with-mail_ssl_module \
    --with-file-aio \
    --with-http_spdy_module \
    --with-ipv6 \
    --with-jemalloc \
    "

ADD ngx_user.patch /
ADD repositories /etc/apk/repositories

RUN \
  addgroup -S nginx \
  && adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
  && apk add --no-cache --virtual .build-deps \
    gcc \
    libc-dev \
    make \
    openssl-dev \
    pcre-dev \
    zlib-dev \
    linux-headers \
    curl \
    jemalloc-dev \
  && curl "http://tengine.taobao.org/download/tengine-$TENGINE_VERSION.tar.gz" -o tengine.tar.gz \
  && mkdir -p /usr/src \
  && tar -zxC /usr/src -f tengine.tar.gz \
  && rm tengine.tar.gz \
  && cd /usr/src/tengine-$TENGINE_VERSION/src/os/unix/ \
  && mv /ngx_user.patch ./ngx_user.patch \
  && patch ngx_user.c ngx_user.patch \
  && rm ngx_user.patch \
  && cd ../../../ \
#  && cd /usr/src/tengine-$TENGINE_VERSION \
  && ./configure $CONFIG --with-debug \
  && make \
  && mv objs/nginx objs/nginx-debug \
  && ./configure $CONFIG \
  && make \
  && make install \
  && rm -rf /etc/nginx/html/ \
  && mkdir /etc/nginx/conf.d/ \
  && mkdir -p /usr/share/nginx/html/ \
  && install -m644 html/index.html /usr/share/nginx/html/ \
  && install -m644 html/50x.html /usr/share/nginx/html/ \
  && install -m755 objs/nginx-debug /usr/sbin/nginx-debug \
  && strip /usr/sbin/nginx* \
  && runDeps="$( \
    scanelf --needed --nobanner /usr/sbin/nginx \
      | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
      | sort -u \
      | xargs -r apk info --installed \
      | sort -u \
  )" \
  && apk add --virtual .nginx-rundeps $runDeps \
  && apk del .build-deps \
  && rm -rf /usr/src/nginx-$NGINX_VERSION \
  && apk add --no-cache gettext \
  \
  # forward request and error logs to docker log collector
  && ln -sf /dev/stdout /var/log/nginx/access.log \
  && ln -sf /dev/stderr /var/log/nginx/error.log

COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

我们知道,Docker 可以根据 Dockerfile 构建镜像,上面就是笔者写的 Dockerfile。首先,使用 FROM 指令指定此镜像的基镜像为 alpine:3.3,第二行为 Dockerfile 维护者声明,然后使用两个 ENV 指令声明两个环境变量,一个指定 Tengine 需要获取的版本号,一个则是编译安装选项。这里暂时不讲解,然后将一个补丁文件和 alpine 镜像源配置文件复制到容器内,实际上是因为 tengine v2.1.2 存在着一个遗留的 glibc bug,会导致编译时出错,上游 Nginx 的最新代码已经修复,而 tengine 的开发分支上面也已经修复了这个问题,笔者前不久提 issue 将此补丁修正了 tengine v2.1.3 分支的代码,但是很可惜,v2.1.3 版本尚未有正式发布,所以只能先使用补丁手动修复此问题。至于镜像源,则是因为国内存在着网络问题,导致 apk 包管理命令无法成功下载各个依赖项,所以将其指定为了国内源,如果正式使用则可以移除这两个文件。

然后就是使用 RUN 命令执行代码,这里大家可以看到笔者使用 && 和 \ 将所有的指令都压缩为了一行,这里是有两个原因:

RUN 指令不会保存上一条指令的工作路径,每条 RUN 指令都只会将工作目录指定为 / 目录
一条 Dockerfile 中的指令就会产生一次镜像的提交,换言之,减少 Dockerfile 中的指令就可以提高镜像的复用水平
然后就是使用 apk 包管理命令下载安装包括编译器等依赖项,并且将这些依赖项标记为 .build-deps 组,便于后面将其卸载清理。然后就是非常常规的思路,./configure && make && make install,编译选项都是非常中规中矩的,基本熟悉 Nginx 编译的朋友都能看懂。但是上面可以注意到,Nginx 被编译了两次,一次开启了 --with-debug 参数,一次没有,这是因为在很多情况下,我们需要 Nginx 提供 debug 级别的监控日志,特别是在开发环境下,所以就编译了两次,便于使用。然后后面使用字符串分析处理将 Tengine 的运行时依赖项提取出来,标记为 .nginx-rundeps 然后卸载 .build-deps,最后则是两个符号链接将 accessLog 和 errorLog 链接到标准输入输出,这样我们就能使用 docker logs 命令方便的查看日志了。最后则是复制自定义的 Nginx 配置文件,然后使用 nginx -g daemon off; 让 Nginx 以前台进程方式运行。

总结

到这里已经讲完了 Docker 在生产开发中的正确使用方法,Docker 也确实是一样不可多得的好工具,祝愿大家早日使用 Docker 提升自己的生产力。

(0)

相关推荐

  • 利用python自动生成docker nginx反向代理配置

    利用python自动生成docker nginx反向代理配置 由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候,自动生成nginx反向代理,然后reload nginx 我的原则是尽量简单,轻量,内存占用少 目标很明确,只要能监听到docker的容器启动/停止事件,即可 网上查了一下可以用docker events来监听docker事件,试了一下

  • Docker容器中运行nginx

    nginx简介 Nginx是一款面向性能设计的HTTP服务器,相较于Apache.lighttpd具有占有内存少,稳定性高等优势.与旧版本(<=2.2)的Apache不同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强.整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活. 在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高.同时Nginx在OpenBSD或FreeBSD

  • Docker搭建 Nginx+PHP+MySQL 环境并部署WordPress实践

    Docker基于LXC实现了把软件封装到一个完整的文件系统,可以在docker容器中运行所需的一切代码,运行环境,系统工具和系统库.由于docker使用独立于主机的文件系统,可以确保软件在不同的主机环境中仍然保持运行环境不变.docker与主机共用一个操作系统内核,使用docker容器具有轻量级的特点,能占用更少的内存快速启动容器. 下面我们学习使用docker来部署目前非常流行的博客系统wordpress的运行环境nginx php mysql.那么docker部署wordpress的运行环境

  • 利用Docker制作Nginx+PHP镜像的步骤详解

    前言 这篇文章给大家介绍的是使用Docker制作nginx+php的镜像,本文里的镜像是centos + nginx 1.9.7 + php 5.6.14,下面话不多说,直接看实现的步骤吧. 1.首先下载到nginx和php: nginx-1.9.5.tar.gz 下载:http://nginx.org/en/download.html php-5.6.14.tar.gz   下载:>http://php.net/downloads.php 2.以及扩展包so: memcache-2.2.4.t

  • Docker容器配置Nginx实例分享

    作为目前最火的应用,Docker 确实存在着其独到之处,无论是程序猿还是运维都应该听说过 Docker 的大名,Docker 已经走过了许多的坑,目前最新版本是 v1.11.0 版本,应该说是完全能承载开发使用和运维监控,这款工具能帮助我们高效的打包.发布和运行承载着应用程序的容器系统.而且收集日志.帮助 App 的快速开发都有很大作用. 容器和虚拟机,经常是被拿出来对比的两款产品,实际上两者有着根本的差别,虚拟机是完全模拟了一台真实计算机,在上面运行的系统可能或者不可能知道自己运行在虚拟化环境

  • docker完整配置nginx+php+mysql的方法步骤

    首先了解一个方法: 使用docker exec进入Docker容器 docker在1.3.X版本之后还提供了一个新的命令exec用于进入容器,这种方式相对更简单一些,下面我们来看一下该命令的使用: sudo docker exec --help 接下来我们使用该命令进入一个已经在运行的容器 $ sudo docker ps $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 一. 配置nginx 查找Docker Hub上的 nginx 镜像 runoob

  • IOS开发教程之put上传文件的服务器的配置及实例分享

    1,HTTP常见的方法 GET 获取指定资源 POST 2M 向指定资源提交数据进行处理请求,在RESTful风格中用于新增资源 HEAD 获取指定资源头部信息PUT 替换指定资源(不支持浏览器操作)DELETE 删除指定资源 2,配置服务器的put请求方式: 复制代码 代码如下: 1> n 打开终端p cd /etc/apache2p sudo vim httpd.conf n 在vim中输入p /httpd-dav.conf• 查找httpd-dav.confp 按0将光标移动至行首 p 按

  • Linux系统安装docker并用ssh登录docker容器的操作方法

    说明:我使用的是Centos安装docker 第一步:安装docker sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.daocloud.io/docker/linux/centos/docker-ce.repo sudo yum install -y -q --setopt=obsoletes=0 docker-ce-17.09.1.ce* docker-ce-selinux-1

  • Docker容器之内网独立IP访问的方法

    实验介绍 今天在学习Docker容器的时候,在虚拟机中创建并开启了一个nginx的container,然后通过端口映射的方法,即将container的80端口映射到虚拟机的80端口,然后在宿主机上通过访问虚拟机的IP从而访问到Docker容器的Nginx服务. 然后开始思考,能否通过分配给container一个独立的IP,然后在宿主机上访问这个独立IP从而访问Nginx服务.通过各种探索,百度,最终实现,下面开始实验,这里用的是虚拟机的NAT模式. 实验图解 实验实施 安装docker服务 [r

  • Docker容器的Tengine实践

    作为目前最火的应用,Docker 确实存在着其独到之处,无论是程序猿还是运维都应该听说过 Docker 的大名,Docker 已经走过了许多的坑,目前最新版本是 v1.11.0 版本,应该说是完全能承载开发使用和运维监控,这款工具能帮助我们高效的打包.发布和运行承载着应用程序的容器系统.而且收集日志.帮助 App 的快速开发都有很大作用. 容器和虚拟机,经常是被拿出来对比的两款产品,实际上两者有着根本的差别,虚拟机是完全模拟了一台真实计算机,在上面运行的系统可能或者不可能知道自己运行在虚拟化环境

  • Docker 手动配置容器网络实例详解

    Docker 手动配置容器网络 docker容器的网络是net命名空间与虚拟设备的结合,容器在启动时会创建一对虚拟接口veth pair,这一对接口分别放到本地和容器中,在本地的veth会被分配类似vethxxxx的名称并被桥接到指定网桥的上(默认为docker0),可以通过brctl show命令查看网桥上挂载的接口,在容器中的veth会从网桥获取一个未使用地址,该veth的名称会被更改为eth0并配置默认路由到vethxxxx,docker允许在启动容器的时候通过--net参数指定不同的网络

  • Docker容器化部署尝试——多容器通信(node+mongoDB+nginx)

    原因是这样的 想要部署一个mocker平台,就在朋友的推荐下选择了 api-mocker 这个现成的项目 该项目分为服务端node.客户端vue.以及数据库mongoDB 在尝试直接部署的时候发现需要装一大堆的环境,node.mongo.nginx啊,特别的麻烦,之前简单的使用过docker,就在想能不能用docker免环境直接部署呢?于是就有了这次的尝试 多容器通信 该项目分为3个部分,于是就要建立3个容器(node.mongo.nginx) 那容器之间怎么实现通信呢? # 通过link指令建

  • Vuejs+vue-router打包+Nginx配置的实例

    其实这个网上已经有了很多人写了,为什么我还要再写这一篇博客?因为我亲身把他们生产的坑给踩了个通透(摊手. 正文开始 本次的项目是基于vue-cli生成的项目,采用的vue-router的history模式.到这里相信大部人还是类似了,接下来就是一个坑死人不偿命的网上诸多博客都在采用的巨坑. 在进行打包的时候,很多博客里都写了,将/config/index.js下,build中的assetsPublicPath从/改为./.我很后悔,为什么当初这样照做的时候不去思考为什么,为什么要这样做,凭什么?

随机推荐