
前言
nginx 是一个高性能的开源反向代理服务器和 web 服务器,一般用来搭建静态资源服务器、负载均衡器、反向代理,本文将分享其在 Windows/docker 中的使用,使用 nssm 部署成服务的方案脚本,局域网中自定义域名解决https提示不安全的解决方案,以及一路踩过的坑。
特点
使用情况
实践
准备
本文版本:v1.24.0
使用端口:80 443
最基本组成:一个 server 节点一个域名配置,要添加其他配置添加 server 节点即可
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name localhost;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
```
Windows 安装使用 nginx
安装运行
直接官网下载即可 v1.24.0
下载后解压到:D:\Software\nginx-1.24.0
在目录输入框打开 cmd 并运行:start nginx
运行 nginx,如果端口没有被占用的话访问 localhost 即可出现 welcome 页面


尝试修改配置:D:\Software\nginx-1.24.0\confi\nginx.conf 添加一个文本返回

添加的文本及 json 返回
#server{....
#返回文本
location /text {
add_header Content-Type text/plain;
return 200 'This is a plain text response.';
}
#返回json
location /json {
add_header Content-Type application/json;
return 200 '{"message": "This is a JSON response.233"}';
}
#默认配置
location / {
root html;
index index.html index.htm;
}
#...}
```
域名配置
因在本地测试,所以需要使用域名访问到 nginx,需要配置 hosts(服务器外网域名配置就将域名解析到服务器)
添加一条记录:127.0.0.1 ``nginx.devops.test.com
现在默认就访问nginx.devops.test.com
的时候就请求到了 nginx 的默认配置了,nginx 默认监听了 localhost:80 使其返回我们指定的内容

添加 server 配置节点,重载配置后访问,即可看到访问显示了配置中的内容
server {
listen 80;
server_name nginx.devops.test.com;
location / {
add_header Content-Type text/plain;
return 200 'nginx.devops.test.com';
}
}
```


因为浏览器的一些机制,可能会自己默认跳转到 https,然后还看不到协议,此时就需要手动改下
SSL 证书申请
为了给网站加把锁(数据传输的私密性),一般个人项目用免费的就行,不过有限制,比如通配符、有效期、安全性等,企业一般会使用付费证书,自行购买即可,一般云商也会提供免费证书,其他免费的目前使用过的就下面两种
如果本地也需要使用 https 的话,也可以通过 nginx 来配置证书,为应用加把锁。服务器的证书配置使用上面两种生成,参考下面配置即可
nginx 本地配置 https
#依次执行,输入信息,我这里都输入了 ym
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl genrsa -out ca.key 1024
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

生成 CA 证书(所在目录:D:/Software/nginx-1.24.0/ssl)
winpty openssl genrsa -des3 -out myCA.key 2048
winpty openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
```
导入 myCA.pem 证书到受信任的根证书颁发机构(Win+R 打开:certlm.msc
)

创建 CA 签名证书(不同域名创建不同的证书)
winpty openssl genrsa -out nginx.devops.test.com.key 2048
winpty openssl req -new -key nginx.devops.test.com.key -out nginx.devops.test.com.csr
创建 X509 V3 证书扩展配置文件 nginx.devops.test.com。ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = nginx.devops.test.com
```
生成证书
winpty openssl x509 -req -in nginx.devops.test.com.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out nginx.devops.test.com.crt -days 825 -sha256 -extfile nginx.devops.test.com.ext
```
配置 nginx
server {
listen 80;
listen 443 ssl;
server_name nginx.devops.test.com;
ssl_certificate D:/Software/nginx-1.24.0/ssl/nginx.devops.test.com.crt;
ssl_certificate_key D:/Software/nginx-1.24.0/ssl/nginx.devops.test.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
add_header Content-Type text/plain;
return 200 'nginx.devops.test.com666';
}
}
```
成功,没有不安全字样了

如果要在局域网其他机器访问,也需要执行第 2 步操作导入 myCA.pem 证书,并配置对应的 hosts
使用 nssm 创建 nginx 服务
每次改完配置还要敲命令重启,开机还要启动,那很明显是不太方便的,所以部署 nginx 服务就很有必要了
和 Windows 计划任务设置开机启动相比,我更倾向和习惯于使用 nssm (一个服务封装程序,它可以方便的将程序封装成 windows 服务运行)来为应用创建一个服务进行管理。
下面分享两个快速创建服务的脚本及使用。通过这两个脚本,只需修改对应路径,就可以为应用创建服务并做到开机自启了
添加一个启动 nginx 的脚本 start.bat
放在 nginx 目录中(D:\Software\nginx-1.24.0\start.bat ) ,以管理员 身份运行即可删除 nginx 进程并重新启动
删除进程并重启,测试环境使用,生产环境不建议直接使用
@echo off
cd /d %~dp0
echo kill nginx
taskkill /fi "imagename eq nginx.EXE" /f
echo start nginx
start nginx
echo start nginx success
pause
将 start.bat 脚本使用 nssm 的方式设置为服务 nssm v2.24 下载
下载后解压:D:\Software\nssm\nssm-2.24\win64
在目录添加 Nginx-service.bat,以快速创建并启动 nginx 服务,根据需要修改服务名和 nginx 启动脚本的路径即可
以管理员 身份运行,即可创建并启动服务,
至此,电脑重启服务也将自启,并且还可以通过服务的重新启动来重启应用
常用命令
使用 Docker Compose 安装 nginx
本篇文章基于 Docker V24 及 Docker Compose V2,安装可以参考之前的文章
配置说明
镜像版本:nginx:1.24.0
指定端口:80 443
指定时区:TZ : 'Asia/Shanghai'
,让日志文件显示北京时间
指定挂载目录
./config/nginx.conf:/etc/nginx/nginx.conf
:默认配置文件,会加载 conf.d 下的所有配置
./config/conf.d:/etc/nginx/conf.d
:自定义配置文件
./html:/usr/share/nginx/html
:默认的静态文件目录
./logs:/var/log/nginx
:默认的日志目录
./ssl:/ssl
:证书目录,配置中使用 /ssl/xxx 指定
配置重载:docker exec nginx_1_24 nginx -s reload
指定网络:devopsnetwork (docker network create devopsnetwork
)
目录结构

配置文件 compose.yml
version: '3.1'
services:
nginx:
image: nginx:1.24.0
container_name: nginx_1_24
restart: always
environment:
TZ : 'Asia/Shanghai'
ports:
- "80:80"
- "443:443"
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/conf.d:/etc/nginx/conf.d
- ./html:/usr/share/nginx/html
- ./logs:/var/log/nginx
- ./ssl:/ssl
networks:
- devopsnetwork
networks:
devopsnetwork:
external: true
默认的 nginx.conf v1.24
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
自定义配置 conf.d/default.conf
将前文 Windows 的配置部分修改到 default.conf 如下所示
server {
listen 80;
listen 443 ssl;
server_name nginx.devops.test.com;
ssl_certificate /ssl/nginx.devops.test.com.crt;
ssl_certificate_key /ssl/nginx.devops.test.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
add_header Content-Type text/plain;
return 200 'nginx.devops.test.com 001';
}
}
创建证书 ssl 目录
上传生成的 ssl 证书或者在 linux 中使用上面 openssl 的方式重新生成域名证书,然后本地添加 pem 证书,即可使用 https
Nginx 的应用
本地使用域名前的配置
要想在局域网使用自定义的域名访问应用,需要先配置 hosts 文件,这里使用 hosts 将域名请求指向目标服务器 192.168.123.214
192.168.123.214 apollo.devops.test.com
192.168.123.214 rabbitmq.devops.test.com
还可以搭建一个 dns 服务,设置本机的 dns,即可将域名请求交友 dns 解析到对应服务,并且能够实现泛解析
Apollo 的转发配置
Apollo 面板地址:http://192.168.123.214:8070/
设定域名:apollo.devops.test.com
对应 server 配置,因为同属一个网络,所以使用容器名加端口访问即可
server {
listen 80;
server_name apollo.devops.test.com;
location / {
proxy_pass http://apollo_portal_2_1:8070/;
#上游主机名
proxy_set_header Host $host;
# 客户端发送的原始主机名
#proxy_set_header host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Apollo 配置 https,并重定向 http 到 https
server {
listen 80;
server_name apollo.devops.test.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name apollo.devops.test.com;
ssl_certificate /certs/apollo.devops.test.com/server.crt;
ssl_certificate_key /certs/apollo.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://apollo_portal_2_1:8070/;
proxy_set_header host $http_host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header x-forwarded-proto $scheme;
}
}
```
RabbitMQ 的转发配置
RabbitMQ 面板地址:http://192.168.123.214:15672/#/
设定域名:rabbitmq.devops.test.com
对应 server 配置,因为同属一个网络,所以使用容器名加端口访问即可
server {
listen 80;
server_name rabbitmq.devops.test.com;
location / {
proxy_pass http://rabbitmq_3_12:15672/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
RabbitMQ 配置 https,并重定向 http 到 https
server {
listen 80;
server_name rabbitmq.devops.test.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name apollo.devops.test.com;
ssl_certificate /certs/apollo.devops.test.com/server.crt;
ssl_certificate_key /certs/apollo.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://apollo_portal_2_1:8070/;
proxy_set_header host $http_host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header x-forwarded-proto $scheme;
}
}
```
相关脚本汇总
脚本本地目录预览,添加了系统判断 linux,执行需要给要执行的脚本添加执行权限:chmod +x ./01.build-pem.sh

nginx-start.bat :删除 nginx 进程并启动 nginx 服务
@echo off
cd /d %~dp0
echo kill nginx
taskkill /fi "imagename eq nginx.EXE" /f
echo start nginx
start nginx
echo start nginx success
pause
```
nginx-nssm-service.bat 创建 nginx 服务脚本
@echo off
cd /d %~dp0
nssm stop Nginx-service
nssm remove Nginx-service confirm
nssm install Nginx-service D:\Software\nginx-1.24.0\start.bat
sc start Nginx-service
pause
```
01.build-pem.sh 创建自签证书
#!/bin/sh
# 生成根证书,访问客户端需要安装导入 myCA.pem,根据myCA.key,myCA.pem再生成nginx需要的证书
if uname | grep -q "MINGW"; then
winpty openssl genrsa -out myCA.key 2048
winpty openssl req -x509 -new -nodes -key myCA.key -days 1825 -out myCA.pem
else
openssl genrsa -out myCA.key 2048
openssl req -x509 -new -nodes -key myCA.key -days 1825 -out myCA.pem
fi
```
02.build-ssl.sh 创建域名证书
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: Must supply a domain"
exit 1
fi
DOMAIN=$1
mkdir $DOMAIN
#!/bin/sh
if uname | grep -q "MINGW"; then
winpty openssl genrsa -out $DOMAIN/server.key 2048
winpty openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr
else
openssl genrsa -out $DOMAIN/server.key 2048
openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr
fi
cat >$DOMAIN/server.ext <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = $DOMAIN
EOF
if uname | grep -q "MINGW"; then
winpty openssl x509 -req -in $DOMAIN/server.csr -CA ./myCA.pem -CAkey ./myCA.key -CAcreateserial -out $DOMAIN/server.crt -days 36500 -extfile $DOMAIN/server.ext
else
openssl x509 -req -in $DOMAIN/server.csr -CA ./myCA.pem -CAkey ./myCA.key -CAcreateserial -out $DOMAIN/server.crt -days 36500 -extfile $DOMAIN/server.ext
fi
```
03.gen.sh 先创建自签证书,再执行 gen.sh 生成需要的域名证书,配置到 nginx 即可
#!/bin/bash
# 获取当前脚本所在目录
script_dir=$(dirname "$0")
sh $script_dir/02.build-ssl.sh nginx.devops.test.com
sh $script_dir/02.build-ssl.sh apollo.devops.test.com
sh $script_dir/02.build-ssl.sh rabbitmq.devops.test.com
```
踩过的坑
Windows 环境 nginx -s reload 后多个 nginx 进程
目前只能通过taskkill /fi "imagename eq nginx.EXE" /f
删除进程再启动
Windows 中使用 openssl 需要添加前缀 winpty openssl
一开始是执行 openssl genrsa -out server.key 2048
命令卡死
后面找到一篇文章说是 git bash 密码的问题,加了密码参数确实可以了:openssl genrsa -des3 -out myCA.key -passout pass:mima 2048
但是后续使用 openssl req
还是卡死,
最后解决自签证书授信的时候才发现是需要加上 winpty 使用才是正解
本地自签证书配置 https 浏览器依旧提示不安全
生产对应域名的证书,并在客户端安装证书,找到的 解决方案 ,以及思路来源 stackoverflow
容器中 nginx.conf 默认配置问题
不同的版本可能默认配置不一样,可以先不挂载配置把容器的默认配置文件复制出来,在默认配置基础上进行修改,可少走弯路。尤其如果是将 Windows 上面 的配置修改到容器中,需要注意路径问题。
比如 windows 中配置静态站点根目录:root html;
,在容器中则需要配置为root /usr/share/nginx/html;
才生效
容器中重载配置
docker exec nginx_1_24 nginx -s reload
后语
一直都是用到了就搜索,此番整理,加深使用,以备后用
最深刻的是本篇对局域网自定义域名不安全https提示问题的解决,简直赏心悦目。
链接:https://www.cnblogs.com/morang/p/devops-nginx-install-use.html#5225281
(版权归原作者所有,侵删)