nginx在docker容器中自动生成配置文件

公司在搭建docker自动化部署时,需要制作一个nginx镜像在其docker run时通过外部指定环境变量使得容器中的配置文件自动生成,不需要再到容器里改配置文件。

实现思路

最后运行的命令大概是这样:

docker run -d -p 80:80 -e xxx=xx 镜像名称 镜像中脚本路径

这里的脚本会代替dockerfile中的CMD指令,所以我们要构建一个自动生成且启动nginx的shell脚本。

#!/bin/bash

#从环境变量里面获取lt开头,为了与其他环境变量区别开,例如lt_analysis=172.17.0.1:8083
result=""
for a in $(env | grep ^lt)
do
 OLD_IFS="$IFS"
 IFS="_"
 arr=($a)
 b=${arr[1]}
 IFS="="
 arr=($b)
 IFS="$OLD_IFS"
 result="${result}
  location /${arr[0]}/ {
    proxy_pass  http://${arr[1]}/${arr[0]}/;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
  }"
done
#将nginx配置文件中nginx_conf中置换成变量result
sed -i "s|nginx_conf|$(echo ${result})|g" /etc/nginx/nginx.conf
cd /usr/sbin
./nginx

需要说明的一点是业务中并不需要将整个配置文件生成,只需要将其中location生成然后替换原配置文件中标记的位置,下面就是原配置文件标记的位置。

http {
  ...

  server {
    ...

    location / {
      root  html;
      index index.html index.htm;
    }

    nginx_conf

    #error_page 404       /404.html;
    ...

我以为将这个shell脚本和默认的配置文件放入nginx的dockerfile镜像中,然后就成功了,但是...运行上述命令之后容器没有起来,查看容器日志,出来的信息却是***Syntax error: “(” unexpected***。我的shell脚本在centos上经过测试是可以运行的,那么为什么会报这个错呢? 经过排查,原来是dockerfile使用基础镜像是官方nginx,官方的镜像使用Ubuntu不再使用bash来而是dash执行shell脚本,真是个坑 。没办法我只好修改dockerfile,下面就是使用基础镜像centos。

FROM centos

ENV NGINX_VERSION 1.10.3
ENV OPENSSL_VERSION 1.0.2k
ENV PCRE_VERSION 8.40
ENV ZLIB_VERSION 1.2.11
ENV BUILD_ROOT /usr/local/xx/nginx

# 为了减小最终生成的镜像占用的空间,这里没有执行yum update命令,可能不是好的实践
# 为了加快构建速度,这里使用了163的安装源
#RUN yum -y update \
RUN yum -y install curl \
  && mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup \
  && curl http://mirrors.163.com/.help/CentOS7-Base-163.repo -o /etc/yum.repos.d/CentOS7-Base-163.repo \
  && yum -y install gcc gcc-c++ make perl zip unzip \
  && mkdir -p $BUILD_ROOT \
  && cd $BUILD_ROOT \
  && curl https://ftp.pcre.org/pub/pcre/pcre-$PCRE_VERSION.zip -o $BUILD_ROOT/pcre-$PCRE_VERSION.zip \
  && curl https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz -o $BUILD_ROOT/openssl-$OPENSSL_VERSION.tar.gz \
  && curl http://www.zlib.net/zlib-$ZLIB_VERSION.tar.gz -o $BUILD_ROOT/zlib-$ZLIB_VERSION.tar.gz \
  && curl https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o $BUILD_ROOT/nginx-$NGINX_VERSION.tar.gz \
  && tar vxzf nginx-$NGINX_VERSION.tar.gz \
  && unzip pcre-$PCRE_VERSION.zip \
  && tar vxfz zlib-$ZLIB_VERSION.tar.gz \
  && tar vxfz openssl-$OPENSSL_VERSION.tar.gz \
  && cd nginx-$NGINX_VERSION \
  && BUILD_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 \
    --with-openssl=$BUILD_ROOT/openssl-$OPENSSL_VERSION \
    --with-pcre=$BUILD_ROOT/pcre-$PCRE_VERSION \
    --with-zlib=$BUILD_ROOT/zlib-$ZLIB_VERSION \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-threads \
    " \
  && mkdir -p /var/cache/nginx \
  && ./configure $BUILD_CONFIG \
  && make && make install \
  && rm -rf $BUILD_ROOT \
  && yum -y remove gcc gcc-c++ make perl zip unzip \
  && yum clean all

#替换nginx默认文件
COPY nginx.conf /etc/nginx/
#添加自动生成配置文件的shell脚本
COPY 脚本名称 /root/

#暴露端口
EXPOSE 80 443

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

提醒:docker容器不支持后台运行,当命令执行之后,容器也会自然退出,这里我们需要将nginx配置文件设置一下

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid    logs/nginx.pid;
daemon off;  //这里添加,关闭后台运行
events {
  worker_connections 1024;
}

http {

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Docker nginx安装与配置挂载的方法

    在Docker下载Nginx镜像 docker pull nginx docker images 创建挂载目录 mkdir -p /data/nginx/{conf,conf.d,html,logs} 编写nginx,conf配置文件,并放在文件夹中 # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Rus

  • 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

  • Docker容器配置Nginx实例分享

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

  • 为docker中的nginx配置https的方法步骤

    没有 https 加持的网站会逐渐地被浏览器标记为不安全的,所以为网站添加 https 已经变得刻不容缓.对于商业网站来说,花钱购买 SSL/TLS 证书并不是什么问题.但对于个人用户来说,如果能有免费的 SSL/TLS 证书可用将会是非常幸福的事情!Let's Encrypt 就是一个提供免费 SSL/TLS 证书的网站,由于其证书期限只有三个月,所以需要我们用自动化的方式去更新证书.本文将介绍如何为通过 docker 运行的 nginx 中的站点添加 https 支持,并自动完成证书的更新.

  • docker安装nginx并配置通过https访问的方法

    1. 下载最新的nginx的docker image $ docker pull nginx:latest 2. 启动nginx容器 运行如下命令来启动nginx container docker run --detach \ --name wx-nginx \ -p 443:443\ -p 80:80 \ -v /home/evan/workspace/wxserver/nginx/data:/usr/share/nginx/html:rw\ -v /home/evan/workspace/w

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

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

  • nginx在docker容器中自动生成配置文件

    公司在搭建docker自动化部署时,需要制作一个nginx镜像在其docker run时通过外部指定环境变量使得容器中的配置文件自动生成,不需要再到容器里改配置文件. 实现思路 最后运行的命令大概是这样: docker run -d -p 80:80 -e xxx=xx 镜像名称 镜像中脚本路径 这里的脚本会代替dockerfile中的CMD指令,所以我们要构建一个自动生成且启动nginx的shell脚本. #!/bin/bash #从环境变量里面获取lt开头,为了与其他环境变量区别开,例如lt

  • 深入浅析Docker容器中的Patroni

    目录 创建镜像 文件结构 DockerFile entrypoint.sh function generatefile 构建镜像 运行镜像 总结 附图 上一篇文章向大家介绍了Repmgr的搭建过程,实现了自动切换,今天将向大家介绍,如何搭建容器下的Patroni集群环境,Patroni作为开箱即用PG高可用工具,越来越多的被各个厂商用于云环境下使用. patroni基本架构如图所示: etcd作为分布式注册中心.进行集群选主工作:vip-manager为主节点设置漂移IP:patroni负责引导

  • .Net项目在Docker容器中开发部署

    .NET多年以前已经开始支持Docker,但由于国内.net现状,生产过程中几乎用不到docker支持,趁着有点时间捣鼓下. 先期工作 1.首先安装Docker Desktop 2.安装Visual Studio 创建项目 使用VS分别创建一个ASP.NET Core Api(WebApplication1)与 ASP.NET Core 应用(WebApplication2) 如果项目已经存在,可以选中项目,右键点击->选择添加Docker支持. 在弹出对话框中选择Linux. 项目支持dock

  • 如何隔离docker容器中的用户的方法

    笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果你已经了解了 Linux 的 user namespace 技术(参考<Linux Namespace : User>),那么自然会问:docker 为什么不利用 Linux user namespace 实现用户的隔离呢?事实上,docker 已经实现了相关的功能,只是默认没有启用而已.笔者将在

  • docker容器中布置静态网站的实现

    服务器布置 这里推荐使用云服务器(阿里云.华为云.腾讯云)可以免费使用几天.在我们买了服务器后会遇到如下问题: 本地电脑ping服务器主机发现ping不通,请求超时 我们需要在管理服务器的界面找到安全组那一栏,然后在安全组出入都要加入icmp这个,建议直接一键添加所有. 然后我们在本地电脑就可以ping通服务器了. docker安装 在布置好云服务器后,我们使用apt-get update, apt-get upgrade 更新信息. 然后,我们输入docker,出现如下错误: 接着,我们按照通

  • 在Docker容器中使用Arthas的详细步骤

    Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!是否有一个全局视角来查看系统的运行状况?

  • 在 Docker 容器中运行 PHPMyAdmin的详细步骤

    目录 基本用法 预设服务器 使用 MySQL Docker 容器 使用 Docker Compose 简化部署 配置安装 概括 PHPMyAdmin是 MySQL 和 MariaDB 数据库的流行管理界面.它允许您使用 Web 浏览器与您的模式.表和数据进行交互.phpMyAdmin能够为你的MySQL提供直观.方便的Web管理界面,非常好用. 该项目有一个官方的 Docker 镜像,它简化了在容器化环境中的部署.以下是如何使用图像快速运行新的 PHPMyAdmin 实例. 基本用法 最简单的安

  • 一文教会你在Docker容器中实现Mysql主从复制

    目录 一 主从复制概念 二 主从复制的优势 三 Docker容器实现Mysql主从复制 3.1 创建主服务器容器 3.2 新建主配置文件 my.cnf 3.3 重启master容器实例 3.4 进入mysql-master容器 3.5 在主服务器中创建用户并授权 3.6 创建从服务器容器 3.7 新建主配置文件 my.cnf 3.8 重启slave容器实例 3.9 在主数据库中查看主从同步状态 3.10 进入mysql-slave容器 3.11 在从数据库中配置主从复制 3.12 在从数据库中查

  • 详解如何在 docker 容器中捕获信号

    我们可能都使用过 docker stop 命令来停止正在运行的容器,有时可能会使用 docker kill 命令强行关闭容器或者把某个信号传递给容器中的进程.这些操作的本质都是通过从主机向容器发送信号实现主机与容器中程序的交互.比如我们可以向容器中的应用发送一个重新加载信号,容器中的应用程序在接到信号后执行相应的处理程序完成重新加载配置文件的任务.本文将介绍在 docker 容器中捕获信号的基本知识. 信号(linux) 信号是一种进程间通信的形式.一个信号就是内核发送给进程的一个消息,告诉进程

  • 在Docker容器中不需要运行sshd的原因浅析

    当开始使用Docker时,人们经常问:"我该如何进入容器?",其他人会说"在你的容器里运行一个SSH服务器".但是,从这篇博文中你将会了解到你根本不需要运行SSHd守护进程来进入你的容器.当然,除非你的容器就是一个SSH服务器. 运行SSH服务器是很想当然的,因为它提供了进入容器的简便方式.在我们公司基本上每个人都最少使用过一次SSH.我们中有很大一部分人每天都会使用它,并且他们很熟悉公钥与私钥,无密码登录,密钥代理,甚至有时会使用端口转发和其他不常用的功能.正因如

随机推荐