搭建最新版Nginx,保姆級教程!
原文鏈接:https://www.cnblogs.com/morang/p/devops-nginx-install-use.html
前言
Nginx 是一個高性能的開源反向代理服務(wù)器和 web 服務(wù)器,一般用來搭建靜態(tài)資源服務(wù)器、負載均衡器、反向代理,本文將分享其在 Windows/docker 中的使用,使用 nssm 部署成服務(wù)的方案腳本,局域網(wǎng)中自定義域名解決https提示不安全的解決方案,以及一路踩過的坑。
特點
-
高性能:事件驅(qū)動的異步架構(gòu),能夠處理大量并發(fā)連接。
-
靜態(tài)資源服務(wù)器:部署前端靜態(tài)頁面及靜態(tài)資源。
-
反向代理服務(wù)器:接收客戶端請求,并將請求轉(zhuǎn)發(fā)到后端服務(wù),可以實現(xiàn)負載均衡、請求分發(fā)和緩存等功能。
-
支持 HTTPS。
使用情況
-
配置域名轉(zhuǎn)發(fā)到項目服務(wù)
-
外網(wǎng)穿透請求轉(zhuǎn)發(fā)到局域網(wǎng)服務(wù)器
-
測試環(huán)境項目的 https 配置
-
需要明白 Nginx 默認啟動后會發(fā)生什么?
-
監(jiān)聽指定端口(默認 80)。
-
攔截本機訪問 80 端口的請求到 nginx 來進行處理。
-
可以添加配置監(jiān)聽不同的端口。
-
同樣監(jiān)聽 80,但是可以通過 server_name 來指定不同的域名使用不同的規(guī)則。
-
本地測試可以通過修改 hosts 文件(C:\Windows\System32\drivers\etc\hosts)來將域名請求轉(zhuǎn)發(fā)到本機。
-
服務(wù)器需要解析域名到服務(wù)器 IP,不同的云商還需要注意其安全組,防火墻是否開啟或需要設(shè)置規(guī)則。
-
-
Windows 中路徑需要使用 / 或者 \,如路徑
D:\Software\nginx-1.24.0\sslnginx.conf 需要配置為D:/Software/nginx-1.24.0/ssl/或D:\Software\nginx-1.24.0\ssl\
實踐
準備
-
本文版本:v1.24.0
-
使用端口:80 443
-
最基本組成:一個 server 節(jié)點一個域名配置,要添加其他配置添加 server 節(jié)點即可
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
安裝運行
-
直接官網(wǎng)下載即可 v1.24.0
-
下載后解壓到:D:\Software\nginx-1.24.0
-
在目錄輸入框打開 cmd 并運行:
start nginx運行 nginx,如果端口沒有被占用的話訪問 localhost 即可出現(xiàn) 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(服務(wù)器外網(wǎng)域名配置就將域名解析到服務(wù)器)。
-
添加一條記錄:
127.0.0.1 ``nginx.devops.test.com現(xiàn)在默認就訪問nginx.devops.test.com的時候就請求到了 nginx 的默認配置了,nginx 默認監(jiān)聽了 localhost:80 使其返回我們指定的內(nèi)容。
-
添加 server 配置節(jié)點,重載配置后訪問,即可看到訪問顯示了配置中的內(nèi)容
server {
listen 80;
server_name nginx.devops.test.com;
location / {
add_header Content-Type text/plain;
return 200 'nginx.devops.test.com';
}
}
```

 -
因為瀏覽器的一些機制,可能會自己默認跳轉(zhuǎn)到 https,然后還看不到協(xié)議,此時就需要手動改下。
SSL 證書申請
為了給網(wǎng)站加把鎖(數(shù)據(jù)傳輸?shù)乃矫苄裕?,一般個人項目用免費的就行,不過有限制,比如通配符、有效期、安全性等,企業(yè)一般會使用付費證書,自行購買即可,一般云商也會提供免費證書,其他免費的目前使用過的就下面兩種:
-
在線網(wǎng)站申請:可以在 freessl 根據(jù)需要申請免費/付費證書,其還包含有證書管理和到期提醒等服務(wù)。
-
win-acme:一個免費的開源工具,用于 Windows 上的 Let's Encrypt 證書的自動化獲取和續(xù)訂。
如果本地也需要使用 https 的話,也可以通過 nginx 來配置證書,為應(yīng)用加把鎖。服務(wù)器的證書配置使用上面兩種生成,參考下面配置即可。
Nginx 本地配置 https
-
使用 openssl 生成自簽證書(會提示不安全,下一步解決)
#依次執(zhí)行,輸入信息,我這里都輸入了 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

-
從圖里面可以看到都加上 https 了,怎么還是不安全,甚至第一次還被攔截了,這個是瀏覽器機制問題,找了一晚上,終于找到了解決方案 思路來源 stackoverflow,下面詳細說明步驟:
-
生成 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 證書到受信任的根證書頒發(fā)機構(gòu)(Win+R 打開:
certlm.msc)
-
創(chuàng)建 CA 簽名證書(不同域名創(chuàng)建不同的證書)
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
-
創(chuàng)建 X509 V3 證書擴展配置文件 nginx.devops.test.com
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';
}
}
``` -
成功,沒有不安全字樣了

-
如果要在局域網(wǎng)其他機器訪問,也需要執(zhí)行第 2 步操作導入 myCA.pem 證書,并配置對應(yīng)的 hosts。
使用 nssm 創(chuàng)建 nginx 服務(wù)
-
每次改完配置還要敲命令重啟,開機還要啟動,那很明顯是不太方便的,所以部署 nginx 服務(wù)就很有必要了。
-
和 Windows 計劃任務(wù)設(shè)置開機啟動相比,我更傾向和習慣于使用 nssm (一個服務(wù)封裝程序,它可以方便的將程序封裝成 windows 服務(wù)運行)來為應(yīng)用創(chuàng)建一個服務(wù)進行管理。
-
下面分享兩個快速創(chuàng)建服務(wù)的腳本及使用。通過這兩個腳本,只需修改對應(yīng)路徑,就可以為應(yīng)用創(chuàng)建服務(wù)并做到開機自啟了。
-
添加一個啟動 nginx 的腳本 start.bat
-
放在 nginx 目錄中(D:\Software\nginx-1.24.0\start.bat ) ,以管理員 身份運行即可刪除 nginx 進程并重新啟動。
-
刪除進程并重啟,測試環(huán)境使用,生產(chǎn)環(huán)境不建議直接使用。
-
@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 的方式設(shè)置為服務(wù) nssm v2.24 下載
-

-
@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
-
下載后解壓:D:\Software\nssm\nssm-2.24\win64
-
在目錄添加 Nginx-service.bat,以快速創(chuàng)建并啟動 nginx 服務(wù),根據(jù)需要修改服務(wù)名和 nginx 啟動腳本的路徑即可。
-
以管理員 身份運行,即可創(chuàng)建并啟動服務(wù)。
-
至此,電腦重啟服務(wù)也將自啟,并且還可以通過服務(wù)的重新啟動來重啟應(yīng)用
-
常用命令
-
啟動:
start nginx -
重載配置:
nginx -s reload如果出錯會回滾到上一次正確配置文件保持正常運行,可能會存在緩存,Ctrl+F5 刷新瀏覽器。 -
停止 nginx(刪除 nginx 進程):
taskkill /fi "imagename eq nginx.EXE" /f-
windows 下使用 nginx 一直有個問題就是重載配置后,不管有沒有問題都可能會啟動多個 nginx 進程,最后重載配置無效,就只能刪除進程后再啟動了。
-
使用 Docker Compose 安裝 nginx
本篇文章基于 Docker V24 及 Docker Compose V2,安裝可以參考之前的文章
配置說明
-
鏡像版本:
nginx:1.24.0 -
指定端口:80 443
-
指定時區(qū):
TZ : 'Asia/Shanghai',讓日志文件顯示北京時間 -
指定掛載目錄
-
./config/nginx.conf:/etc/nginx/nginx.conf:默認配置文件,會加載 conf.d 下的所有配置 -
./config/conf.d:/etc/nginx/conf.d:自定義配置文件 -
./html:/usr/share/nginx/html:默認的靜態(tài)文件目錄 -
./logs:/var/log/nginx:默認的日志目錄 -
./ssl:/ssl:證書目錄,配置中使用 /ssl/xxx 指定
-
-
配置重載:
docker exec nginx_1_24 nginx -s reload -
指定網(wǎng)絡(luò):devopsnetwork (
docker network create devopsnetwork) -
目錄結(jié)構(gòu)

配置文件 compose.yml
-
將準備好的 compose.yml config ssl html 拷貝到服務(wù)器
-
然后運行
docker compose up -d即可
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';
}
}
創(chuàng)建證書 ssl 目錄
上傳生成的 ssl 證書或者在 linux 中使用上面 openssl 的方式重新生成域名證書,然后本地添加 pem 證書,即可使用 https。
Nginx 的應(yīng)用
-
前面文章我們安裝了 Apollo,RabbitMQ 及各種常用數(shù)據(jù)庫,下面將通過 nginx 給之前文章中的應(yīng)用配置域名轉(zhuǎn)發(fā)。
-
通過域名訪問到各自應(yīng)用中,而無需再使用 IP+端口來訪問應(yīng)用,這樣就算后面部署方式/IP、端口發(fā)送變化,只需要修改 nginx 的轉(zhuǎn)發(fā)配置即可。
本地使用域名前的配置
要想在局域網(wǎng)使用自定義的域名訪問應(yīng)用,需要先配置 hosts 文件,這里使用 hosts 將域名請求指向目標服務(wù)器 192.168.123.214:
192.168.123.214 apollo.devops.test.com
192.168.123.214 rabbitmq.devops.test.com
還可以搭建一個 dns 服務(wù),設(shè)置本機的 dns,即可將域名請求交友 dns 解析到對應(yīng)服務(wù),并且能夠?qū)崿F(xiàn)泛解析。
Apollo 的轉(zhuǎn)發(fā)配置
Apollo 面板地址:http://192.168.123.214:8070/
設(shè)定域名:apollo.devops.test.com
對應(yīng) server 配置,因為同屬一個網(wǎng)絡(luò),所以使用容器名加端口訪問即可:
server {
listen 80;
server_name apollo.devops.test.com;
location / {
proxy_pass http://apollo_portal_2_1:8070/;
#上游主機名
proxy_set_header Host $host;
# 客戶端發(fā)送的原始主機名
#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 的轉(zhuǎn)發(fā)配置
RabbitMQ 面板地址:http://192.168.123.214:15672/#/
設(shè)定域名:rabbitmq.devops.test.com
對應(yīng) server 配置,因為同屬一個網(wǎng)絡(luò),所以使用容器名加端口訪問即可:
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;
}
}
```
相關(guān)腳本匯總
腳本本地目錄預(yù)覽,添加了系統(tǒng)判斷 linux,執(zhí)行需要給要執(zhí)行的腳本添加執(zhí)行權(quán)限:chmod +x ./01.build-pem.sh

nginx-start.bat :刪除 nginx 進程并啟動 nginx 服務(wù):
@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 創(chuàng)建 nginx 服務(wù)腳本:
@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 創(chuàng)建自簽證書
#!/bin/sh
# 生成根證書,訪問客戶端需要安裝導入 myCA.pem,根據(jù)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 創(chuàng)建域名證書
#!/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 先創(chuàng)建自簽證書,再執(zhí)行 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 環(huán)境 nginx -s reload 后多個 nginx 進程
目前只能通過taskkill /fi "imagename eq nginx.EXE" /f刪除進程再啟動。
-
Windows 中使用 openssl 需要添加前綴
winpty openssl
一開始是執(zhí)行 openssl genrsa -out server.key 2048命令卡死。
后面找到一篇文章說是 git bash 密碼的問題,加了密碼參數(shù)確實可以了:openssl genrsa -des3 -out myCA.key -passout pass:mima 2048,但是后續(xù)使用 openssl req還是卡死,最后解決自簽證書授信的時候才發(fā)現(xiàn)是需要加上 winpty 使用才是正解。
-
本地自簽證書配置 https 瀏覽器依舊提示不安全
生產(chǎn)對應(yīng)域名的證書,并在客戶端安裝證書,找到的 解決方案 ,以及思路來源 stackoverflow。
-
容器中 nginx.conf 默認配置問題
不同的版本可能默認配置不一樣,可以先不掛載配置把容器的默認配置文件復(fù)制出來,在默認配置基礎(chǔ)上進行修改,可少走彎路。尤其如果是將 Windows 上面 的配置修改到容器中,需要注意路徑問題。
比如 windows 中配置靜態(tài)站點根目錄:root html;,在容器中則需要配置為root /usr/share/nginx/html;才生效。
-
容器中重載配置
docker exec nginx_1_24 nginx -s reload
后語
此番整理,加深使用,以備后用。
往期推薦
- 小孩也能學會的 Kubernetes 繪本教程
- 優(yōu)秀的 Shell 運維腳本鑒賞
- 阿里 Nacos 高可用集群部署
- 神器 Nginx 的學習手冊 ( 建議收藏 )
- K8S 常用資源 YAML 詳解
- 我會在Docker容器中抓包了!
- 19 個 K8S集群常見問題總結(jié),建議收藏
- 9 個實用 Shell 腳本,建議收藏!
- 詳解 K8S Helm CI/CD發(fā)布流程
- 一臺服務(wù)器最大能支持多少條TCP連接?
- K8S運維必知必會的 Kubectl 命令總結(jié)
- 16 張圖硬核講解 Kubernetes 網(wǎng)絡(luò)
- 史上最全 Jenkins Pipeline流水線詳解
- 主流監(jiān)控系統(tǒng) Prometheus 學習指南
點亮,服務(wù)器三年不宕機
