速查 配置文件路径:/etc/nginx/nginx.conf
日志路径:/var/log/nginx/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 user root;worker_processes 1 ;error_log /var/log/nginx/error.log;error_log /var/log/nginx/error.log notice ;error_log /var/log/nginx/error.log info ;events { worker_connections 1024 ; } http { include mime.types; default_type application/octet-stream; log_format main '$scheme - ' '$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 ; server { listen 80 ; server_name api.danmoits.com; return 301 https://$host$request_uri; } server { listen [::]:443 ssl ipv6only=on ; listen 443 ssl; server_name api.danmoits.com; index index.js; root /home/Milestone-be/be/src; location /milestone/ { proxy_pass http://127.0.0.1:8080/; } ssl_certificate /etc/nginx/cert/api.danmoits.com.pem; ssl_certificate_key /etc/nginx/cert/api.danmoits.com.key; ssl_session_cache shared:SSL:1m ; ssl_session_timeout 5m ; ssl_ciphers ECDHE-RSA-AES128-GCSHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3 ; ssl_prefer_server_ciphers on ; } server { listen 80 ; server_name milestone.danmoits.com; index index.html; root /home/Milestone-fe; location / { try_files $uri $uri/ /index.html; index index.html index.htm; } } server { listen 80 ; server_name zichen.danmoits.com; index index.html; root /home/remote-sensing; location / { try_files $uri $uri/ /index.html; index index.html index.htm; } } }
location路径替换 我只需要购买一个域名,创建很多二级域名,每个二级域名映射到服务器的一个端口上。实现起来,就是在server_name
处写上域名,再在下面location中的proxy_pass
指明代理到哪个端口。当然只有后端服务才需要这么做,前端只需要把静态资源放上去,指明 server_name 就行了,不需要配置反向代理。
问题:当我请求 api/danmoits.com/milestone/post 时,我希望后端那边收到的请求不带 milestone。
参考: nginx中proxy_pass的使用
假设http的请求路径为:http://123.25.95.148:9998/nginx/hello?name=taolong
1 2 3 4 5 6 location /nginx { proxy_pass http://123.25.95.148:10010/; }
所以我只需要在 /nginx 处写成 /milestone/ (此处必须加 /,不然后端会多一个/,如 //post
)
proxy_pass 处写成 http:127.0.0.1/ (以 / 结尾)
这样就会把未匹配内容加在 http:127.0.0.1/ 后面
try_files 踩坑:刚进入页面时正常,刷新后显示404
由于nginx本质上还是一个托管静态资源的web服务器,当访问domain/url
时,会去我指定的root目录下查找是否有资源。
比如说,milestone.danmoits.com/posts?page=0
,我指定的root是服务器的/home/Milestone-fe
,那么会找/home/Milestone-fe/posts?page=0
,很显然此时找不到,那么就会报404。
为什么刚进入页面时不报404呢?因为我一开始访问的是根目录,请求会打到index.html上,随后前端把url重定向,而/home/Milestone-fe/index.html
是真实存在的,所以没有404,这里的前端重定向,被学长称作’fake router’。
因此,需要配置try_files:
1 try_files $uri $uri/ /index.html;
当用户请求 http://localhost/example
时,这里的 $uri
就是 /example
,try_files 会到硬盘里尝试找这个文件; 如果存在名为 /$root/example
(其中 $root
是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户;
如果这样写,其实try_files前面的$uri
做的事和上边描述的一样,关键在于最后的参数。
如果给出的file都没有匹配到,则会进行一个内部重定向到最后一个参数给定的uri,就是新的location匹配。
即前面都没匹配到,就会去找/index.html
,而它是能找到的,就不会报404了。
https 前端配置 https 借助来 cdn,而后端只能配 nginx.conf。
前端需要明白 cdn 的原理,我们要访问的域名配置了 CNAME 解析,从而访问 cdn 域名,我们发送 https 请求是向 cdn 服务器发送 https 请求,cdn 可能会回源,此时我配置回源协议是 http,所以 nginx 这边就不用配 https 了,当然也可以配,这样的话回源协议需要设置为 https。
以前用 certbot 生成的一份配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 user root;worker_processes auto;events { accept_mutex on ; multi_accept on ; worker_connections 1024 ; } http { include 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; error_log /var/log/nginx/error.log; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 ; ssl_prefer_server_ciphers on ; sendfile on ; tcp_nopush on ; tcp_nodelay on ; keepalive_timeout 65 ; gzip on ; server { listen [::]:443 ssl; listen 443 ssl; server_name milestone.danmoits.com; ssl_certificate /etc/letsencrypt/live/milestone.danmoits.com/fullchain.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /home/Milestone-fe; index index.html index.htm; location / { try_files $uri $uri/ /index.html; } } server { listen 80 ; listen [::]:80 ; server_name milestone.danmoits.com; if ($host = milestone.danmoits.com) { return 301 https://$host$request_uri; } return 404 ; } server { listen [::]:443 ssl ipv6only=on ; listen 443 ssl; server_name api.danmoits.com; ssl_certificate /etc/letsencrypt/live/api.danmoits.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.danmoits.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; index index.js; root /home/Milestone-be/be/src; location /milestone/ { proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080/; } } server { listen 80 ; listen [::]:80 ; server_name api.danmoits.com; if ($host = api.danmoits.com) { return 301 https://$host$request_uri; } return 404 ; } server { listen [::]:443 ssl; listen 443 ssl; server_name cmind.danmoits.com; ssl_certificate /etc/letsencrypt/live/cmind.danmoits.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/cmind.danmoits.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /home/cMind; location / { try_files $uri $uri/ /index.html; index index.html index.htm; } } server { listen 80 ; listen [::]:80 ; server_name cmind.danmoits.com; if ($host = cmind.danmoits.com) { return 301 https://$host$request_uri; } return 404 ; } }
后来自己尝试配 https,参考以下资料:
Configuring HTTPS servers
在Nginx或Tengine服务器上安装证书
然后就有了开头那份 nginx.conf。