多个服务运行在docker容器中,nginx同样在docker容器中
比如前端服务需要请求后端服务,用户请求服务器80或者443 ,nginx代理请求到前端服务,前端服务业务请求到后端服务
- docker network create --driver bridge --subnet 172.30.1.0/24 --gateway 172.30.1.1 my_net
- # my_net 自定义网络名称
- # 172.30.1.0/24 自定义网段
- # geteway 定义
这里使用docker compose
创建了一个remarkbackContainer的容器,指定了端口映射,指定网络,并固定一个ip地址
- version: "3"
- services:
- remarkbackContainer:
- image: remarkback:v1.0
- container_name: remarkbackContainer
- restart: always
- ports:
- - 9012:9012
- networks:
- my_net:
- ipv4_address: 172.30.1.3 #固定ip
- networks:
- my_net:
- external: true
因为前端项目如果直接请求后端服务的地址和端口,那么将后端服务直接暴露出来,使用nginx进行代理则可以隐藏后端服务
在nginx的配置文件中增加匹配
比如,前端请求直接后端接口统一用api路径,[http://demain.com/api/xxx],那么在nginx中这样配置
proxy_pass 可以直接写后端服务的容器名称,这样请确保nginx,前后端服务都在docker 同一个网络中
- location /api{
- proxy_pass http://remarkbackContainer:9012; # 后端服务ip接口
- 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;
- #proxy_set_header access_token $http_access_token;
-
- # 添加 CORS 头信息
- add_header 'Access-Control-Allow-Origin' '*';
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
- add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
- add_header 'Access-Control-Allow-Credentials' 'true';
- add_header 'Access-Control-Max-Age' '86400';
- }
比如使用 jwt进行验证,将token放入了一个 access_token中 ,但是登录成功后仍然需要验证权限,通过后端服务日志查看,header中并没有token信息
原因:
这是因为nginx默认会剔除掉 _ 等特殊字符的header key,需要修改nginx配置
增加 underscores_in_headers on;
- http {
-
-
- include mime.types;
- default_type application/octet-stream;
- sendfile on;
- underscores_in_headers on; # 用于解决请求头中包含下划线'_'的key
- keepalive_timeout 65;
- client_max_body_size 50m;
- ...
- }
1. 先确保在http协议下能正常请求
2. 再确认单独https请求后端服务是否正常
3. 如果不正常,那么是后端服务的https代理未配置好
4. 如果正常,那么可能是前端服务请求后端服务的地址不是https
比如域名是 demain.com,用户请求 https://demain.com时访问了前端服务页面,但是点击操作时前端服务请求后端时出现跨域,如果是请求后端地址不是同一个域名,那么会出现跨域问题
这种情况可以将请求地址改成 https://demain.com/api这种带有固定前缀的,再在nginx上进行转发到实际后端服务上【参考1.3】
如果请求的地址也是经过nginx转发,但是仍然出现,那么就看看后端服务的https转发是否正确,