Docker 打造支持快速部署和迁移的 Nginx 环境
前言
博主在日常折腾时,经常会使用到nginx
来测试网站,或者反代容器等需求.所以整理了一套方便在docker
上使用nginx
的方案.本文并不是详细的使用教程,而是一篇快速部署和迁移的准备工作,适用以下场景:
快速部署
通过下文的前期准备,可以实现在任何服务器上快速部署环境.用完即删,保持服务器干净.快速迁移
各云服务商都会提供了免费试用的服务器,性能低,安装环境太慢,更换服务器后无需频繁安装环境,实现快速迁移.
创建目录
为方便持久化存储和快速迁移,提前规划好相关文件的存放目录.
例如在/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
镜像
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
编辑原始nginx.conf
vi ~/nginx/conf/nginx.conf
新增include
使得vhost
目录下的任何conf
配置文件都能被nginx
读取.
# 查找到 include /etc/nginx/conf.d/*.conf; # 新增一行 include /etc/nginx/conf.d/vhost/*.conf;
完成准备工作
将常用的域名证书上传至
~/nginx/ssl
将网站的
域名conf
或者常用样本conf
上传至~/nginx/vhost
将网页文件以各域名命名的文件夹上传至
~/nginx/html
将整个
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
结语
更进阶的玩法还可以将nginx
,php
,mysql
整合成docker compose
的方式来快速部署,网上已有成熟的方案,博主也在使用.推荐给大家:
本站提供免费和付费的技术支持.你可以通过留言,邮件,QQ的方式来进行技术交流和免费咨询.同时也可以付费支持的方式获得相关的技术支持,项目部署配置等服务.具体相关详情请点击查看 技术支持页面