由于政策的要求,用户发布内容,需要显示ip所在地理位置,在这个问题上,我踩了一些坑。
首先,如果只是单个的nodejs 服务器,目前一般用的是koa 或者eggjs,可以直接使用`ctx.ip` 来获取。
但一般我们会把server 放在nginx 后面,这样,就需要告诉nginx 帮忙转发真实的ip 地址。可以根据eggjs 教程配置:
通过设置 config.proxy = true
可以开启前置代理模式:
// config/config.default.js exports.proxy = true;
配置nginx
location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-Port $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:81; }
获取ip就就简单了
this.ctx.request.ip
但最终我发现我获取到的ip多数是172 开头的ip,经过层层排查,有文章说到是因为docker 网络桥接模式导致的。


network_mode
根本原因是docker 在起服务的时候,有多种网络模式,模式是桥接模式。docker-compose 默认为桥接模式,有单独的子网。
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
要解决真实ip 转发问题,最简单的就是改为使用host 模式,和宿主机共用一个网络。
version: '3.2' abc: image: abc/edf container_name: abc restart: always network_mode: "host"
坏处就是不能使用端口映射了,如果一台宿主机上有多服务在容器内需要使用同一个端口会冲突。
桥接模式也能实现ip 的转发,看教程是说把网桥加入到防火墙的internal(内部)区域,这个还没跑通,暂时先搁置,记录下。