docker 之如何从容器中访问本机的服务

1,014 阅读1分钟

背景

今天为了在家排一个线上的bug,在自己的电脑上搭建了一套开发环境。主要是 nginx + node + vue;

node 作为该项目的路由负责返回 vue 打包好的文件。 nginx 主要负责根据域名监听,将访问指定的域名的请求转发到 node 服务上。请求链路如下:

无标题-2021-10-13-2331.png

搭建开发环境

看到这个开发环境,我无比轻快的开始上手搭建环境。首先写下的搭建环境 checklist:

  • 搭建 nginx 环境
  • 搭建 node 服务器
  • 配置 nginx 配置文件
  • 配置 host 映射 127.0.0.1 www.haohia.com
  • 访问 www.haohia.com

搭建 nginx 环境

本这能省事就省事的原则,在我的电脑上原本就有使用 dokcer 搭建的 nginx 服务。我快乐的直接忽略该步骤。下面是搭建 nginxdocker-compose.yml

version: '2'
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    container_name: "nginx"
    volumes:
      - /Users/mimee/Documents/my-project/docker/nginx/html:/usr/share/nginx/html
      - /Users/mimee/Documents/my-project/docker/nginx/config/nginx.conf:/etc/nginx/nginx.conf
      - /Users/mimee/Documents/my-project/docker/nginx/logs:/var/log/nginx
      - /Users/mimee/Documents/my-project/docker/nginx/config/conf.d:/etc/nginx/conf.d

搭建 node 环境

这里我就起一个最简单的 node server 来作为例子。

const http = require('http');

http.createServer(function(request, response) {
  // 设置响应头
  response.writeHeader(200, {
    "Content-Type" : "text/plain"
  });
  // 响应主体为 "Hello world!"
  response.write("Hello world!");
  response.end();
})
// 设置监听端口为9000
.listen(11104);

配置 nginx 配置文件

这里监听域名 www.haohia.com,并对该域名下的所有资源使用上面用 node 起的服务器进行的代理。

server {  
    listen 80;
    server_name  www.haohia.com;
    index index.html index.htm index.php;
    
    location / {

        if ($uri ~* /heartbeat$ ) {
            access_log off; # 移除该链接的访问日志
        }

        proxy_store off;
        proxy_redirect off;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Remote-Host $remote_addr;
        proxy_set_header X-Nginx-Proxy true;
        proxy_pass http://hello_word;
    }
}

upstream hello_word {
    server 127.0.0.1:11104;
}

配置 host 映射 127.0.0.1 www.haohia.com

我这里使用的是 swichhost 软件进行配置

屏幕快照 2021-10-23 下午8.48.53.png

见证奇迹的时刻

开开心心快快乐乐的在浏览器打开 www.haohia.com

屏幕快照 2021-10-23 下午8.55.38.png

竟然出现 502 !!! 难道是我的服务没有开?

屏幕快照 2021-10-23 下午8.56.27.png

打开 localhost:11104一看,正常呀~~???

经过一番冥思苦想,我认为这是 docker 的锅。使用 docker 搭建的 nginx 不能通过 127.0.0.1 访问到本机。

又是一番百度google检索,成功解决了上述问题。

  1. 进入 docker 容器 docker exec -it nginx /bin/bash
  2. 查看是否有 ping 命令,如果没有运行以下命令安装
    • apt-get update
    • apt-get install iputils-ping
  3. 执行 ping host.docker.internal

屏幕快照 2021-10-23 下午9.03.19.png

ping 后显示的 ip 就是 docker 容器访问本机的 ip 了。

  1. 修改 nginx 配置
server {  
    listen 80;
    server_name  www.haohia.com;
    index index.html index.htm index.php;
    
    location / {

        if ($uri ~* /heartbeat$ ) {
            access_log off; # 移除该链接的访问日志
        }

        proxy_store off;
        proxy_redirect off;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Remote-Host $remote_addr;
        proxy_set_header X-Nginx-Proxy true;
        proxy_pass http://hello_word;
    }
}
##### 此处被修改
upstream hello_word {
    server 192.168.65.2:11104;
    ## 改成 host.docker.internal::11104 也是可以的
}

记得重启 docker 更新配置哈·~

再次见证奇迹

屏幕快照 2021-10-23 下午9.08.15.png