Docker 打造支持快速部署和迁移的 Nginx 环境

前言

博主在日常折腾时,经常会使用到

nginx

来测试网站,或者反代容器等需求.所以整理了一套方便在

docker

上使用

nginx

的方案.本文并不是详细的使用教程,而是一篇快速部署和迁移的准备工作,适用以下场景:

  • 快速部署
    通过下文的前期准备,可以实现在任何服务器上快速部署环境.用完即删,保持服务器干净.
  • 快速迁移
    各云服务商都会提供了免费试用的服务器,性能低,安装环境太慢,更换服务器后无需频繁安装环境,实现快速迁移.

本文为 Stille 原创文章.经实践,测试,整理发布.如需转载请联系作者获得授权,并注明转载地址.

创建目录

为方便持久化存储和快速迁移,提前规划好相关文件的存放目录.
例如在

/root

下创建

nginx

目录,用于集中存放配置文件,证书及网页文件.

mkdir -p ~/nginx/conf
mkdir -p ~/nginx/vhost
mkdir -p ~/nginx/ssl
mkdir -p ~/nginx/html
  • ~/nginx/conf

    用于存放

    nginx 主配置

    文件

  • ~/nginx/vhost

    用于存放

    各站点conf配置

    文件

  • ~/nginx/ssl

    用于存放

    证书

    文件

  • ~/nginx/html

    用于存放

    网页

    文件


配置环境

获取原始 nginx.conf

首次拉取镜像并运行容器,主要为拷贝原始 nginx.conf 配置文件,并修改参数以便后期使用时挂载至容器内.

拉取官方

nginx

镜像

docker pull nginx

首次直接后台运行,以方便拷贝原始

nginx.conf

配置文件.

docker run -d --name=nginx nginx

将原始

nginx.conf

配置文件拷贝至

~/nginx/conf

docker cp nginx:/etc/nginx/nginx.conf ~/nginx/conf

停止并删除容器

docker stop nginx
docker rm nginx

修改原始 nginx.conf

由于此环境可能用于多站点使用,推荐使用 include 调用其他 conf 配置文件的方式来创建网站,这样避免每次修改原始 nginx.conf ,既安全又方便.

编辑原始

nginx.conf

vi ~/nginx/conf/nginx.conf

新增

include

使得

vhost

目录下的任何

conf

配置文件都能被

nginx

读取.

# 查找到
include /etc/nginx/conf.d/*.conf;
# 新增一行
include /etc/nginx/conf.d/vhost/*.conf;

完成准备工作

  1. 将常用的域名证书上传至
    ~/nginx/ssl
  2. 将网站的
    域名conf

    或者常用

    样本conf

    上传至

    ~/nginx/vhost
  3. 将网页文件以各域名命名的文件夹上传至
    ~/nginx/html
  4. 将整个
    nginx

    目录打包存档,上传至网盘,对象存储或者GitHub中.

展开查看

常规 Nginx 样本

server
    {
        listen 80;
        #listen [::]:80;
        server_name www.yourdomain.com ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /usr/share/nginx/html/www.yourdomain.com;

        # return 301 https://www.yourdomain.com$request_uri;

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*/.php$ { deny all; }

        location ~ .*/.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }

        location ~ .*/.(js|css)?$
        {
            expires      12h;
        }

        location ~ /.well-known {
            allow all;
        }

        location ~ //.
        {
            deny all;
        }

        access_log off;
    }

server
    {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name www.yourdomain.com ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /usr/share/nginx/html/www.yourdomain.com;

#        if ($host = 'yourdomain.com') {
#            return 301 https://www.yourdomain.com$request_uri;
#        }

        ssl_certificate /etc/nginx/ssl/yourdomain.com.cer;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        # ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*/.php$ { deny all; }

        location ~ .*/.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }

        location ~ .*/.(js|css)?$
        {
            expires      12h;
        }

        location ~ /.well-known {
            allow all;
        }

        location ~ //.
        {
            deny all;
        }

        access_log off;
    }

Nginx 反向代理其他容器样本

upstream dockername { 
    server 127.0.0.1:8080; # 端口改为docker容器提供的端口
}

server {
    listen 80;
    server_name  www.domain.com;
    return 301 https://www.domain.com$request_uri;
}

server {
    listen 443 ssl;
    server_name  www.domain.com;
    gzip on;    

    ssl_certificate /etc/nginx/ssl/www.domain.com.cer;
    ssl_certificate_key /etc/nginx/ssl/www.domain.com.key;

    # access_log /var/log/nginx/dockername_access.log combined;
    # error_log  /var/log/nginx/dockername_error.log;

    location / {
        proxy_redirect off;
        proxy_pass http://dockername;

        proxy_set_header  Host                $http_host;
        proxy_set_header  X-Real-IP           $remote_addr;
        proxy_set_header  X-Forwarded-Ssl     on;
        proxy_set_header  X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto   $scheme;
        proxy_set_header  X-Frame-Options     SAMEORIGIN;

        client_max_body_size        100m;
        client_body_buffer_size     128k;
        
        proxy_buffer_size           4k;
        proxy_buffers               4 32k;
        proxy_busy_buffers_size     64k;
        proxy_temp_file_write_size  64k;
    }
}

  • 证书路径
    /etc/nginx/ssl/www.yourdomain.com.cer(key)
  • 网站 root 路径
    /usr/share/nginx/html/www.yourdomain.com

快速部署

在新环境需要使用时,直接通过

wget

git clone

nginx目录

拉取到服务器的

/root

下,执行以下命令启动容器,即可快速部署网站.使用过程中新增网站仅需上传网页文件和新建

站点conf

文件并重启容器.

docker run -d --name=nginx --restart=always /
    --network host /
    -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf /
    -v ~/nginx/vhost:/etc/nginx/conf.d/vhost /
    -v ~/nginx/ssl:/etc/nginx/ssl /
    -v ~/nginx/html:/usr/share/nginx/html /
    nginx
关于启动命令多说几句

使用 –network host

使用

--network host

参数是让

nginx

直接使用宿主机服务器的的网络,也就无需映射

80/443

端口.其目的是当有其他容器需要被

nginx

反向代理时,

conf

配置文件中的反代地址

127.0.0.1

能正确的被识别为宿主机.

不使用 –network host

如果

不使用 --network host

,而单独映射

80/443

端口到宿主机,当反向代理到

127.0.0.1:XXXX

的其他容器时是无法成功的.因为此时的

127.0.0.1

实际上是

nginx

这个容器自身的内网IP,并非宿主机的内网IP.

当然可以使用

ifconfig -a

命令查询宿主机的内网IP,替换掉

127.0.0.1

也能够解决.还有可以使用

host.docker.internal

来使容器识别宿主机IP,但是都相对麻烦,也不利于快速部署和迁移.大家可根据自己实际情况选择使用.

特殊需求

如果遇到环境中

80/443

端口被占用,临时需要使用

nginx

,同样可以使用以下映射端口的命令来启动,只是切记在反代时使用宿主机的内网IP.

docker run -d --name=nginx --restart=always /
    -p 8080:80 /
    -p 4443:443 /
    -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf /
    -v ~/nginx/vhost:/etc/nginx/conf.d/vhost /
    -v ~/nginx/ssl:/etc/nginx/ssl /
    -v ~/nginx/html:/usr/share/nginx/html /
    nginx

以上相关文件代码已上传至 GitHub 仓库


结语

更进阶的玩法还可以将

nginx

,

php

,

mysql

整合成

docker compose

的方式来快速部署,网上已有成熟的方案,博主也在使用.推荐给大家:


本站提供免费和付费的技术支持.你可以通过留言,邮件,TG群的方式来技术交流和免费咨询.同时也可以付费支持的方式获得相关的技术支持,项目部署配置等服务.具体相关详情请点击查看 技术支持页面

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享