基于Docker搭建本地网络服务集

239 阅读4分钟

Docker 是一个开源的应用容器引擎,可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

Docker中有很多好用的工具,我们可以利用docker整合一个本地工具集合,提高开发和生活效率。很多工具容器都提供一个Web页面给我们操作,容器内部一般是使用80端口提供服务,但当我们同时开启多个工具容器时,主机80端口只能映射给其中一个,其他需要通过加端口号的方式访问,这种方式不够简洁也不容易记忆。本篇文章提供一种基于nginx的解决方案,可以通过二级域名访问各个服务。

1 安装docker

不赘述,请自行参考教程。

2 启动测试网络服务的容器

httpbin是一个简易http网络服务镜像,可以用来测试各种类型网络请求,在线网址 httpbin.org/。 我们以这个服务为例探索配置流程。

启动容器命令如下:

docker run -d --name httpbin -p 40000:80 kennethreitz/httpbin

启动容器时,我们将主机端口4000映射给了容器端口80,此时,浏览器访问 localhost:4000 或者 127.0.0.1:4000 将看到httpbin首页。

通过指定端口的形式访问是比较丑陋的,我们知道浏览器访问网址,默认是访问80端口,那我们为什么不把80端口直接分配给httpbin容器的?那样访问时就可以去掉端口了。

因为我们开头说过,我们之后可能会使用各种带网络服务的容器,要想同时使用时,80端口只能分配给其中一个,其他的需要通过指定端口访问,那有办法即美观又方便记忆的方法吗?那我们就要引入nginx反向代理了。

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。我们主要使用它的反向代理功能,它可以根据二级域名分发请求给其他服务器。那现在有另一个问题,nginx是根据域名分发请求,那我们本机没有域名怎么办?其实有好几种解决办法。

  1. 本机配置hosts。其实域名解析时会首先查看本机域名配置,我们再本机完成域名与ip地址绑定,缺点是局域网中其他设备无法解析这个域名。Windows下可以参考这篇:win10配置hosts
  2. 路由器hostname。部分路由器支持自定义hostname,我们可以在路由器中配置域名与地址映射,有的路由器支持通配符,可以用*.doman.com这种形式匹配二级域名,有的不支持,需要为二级域名再配置一条hostname。本人路由器为OpenWrt系统,支持自定义hostname,因此采用的是这种方式。
  3. 自己搭一个dns服务器,路由器的dns地址指向我们自己的dns服务器,然后在我们自己的dns服务器中完成域名与地址映射。当然,我们可以使用docker启动一个dns服务器,这也是很容易的。
3 启动Nginx容器

域名配置好了,我们来配置nginx。 以下配置假设您的域名为 yourdomain.com。

启动nginx容器前,先把用到的nginx配置放到对应的容器映射目录。

E:\DockerMapping\nginx/nginx.conf

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;
}

E:\DockerMapping\nginx/nginx.conf/default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  www.yourdomain.com;

    access_log  /var/log/nginx/yourdomain.com.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

E:\DockerMapping\nginx/nginx.conf/httpbin.conf

server {
    listen       80;
    server_name  httpbin.yourdomain.com;

    location / {
        # root   html;
        # index  index.html index.htm;
        proxy_set_header Host $host;
        proxy_set_header X-Real-Ip $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
	# 下面这个ip地址需要替换为你自己docker宿主ip,可以通过ipconfig/ifconfg查看
        proxy_pass http://172.18.48.1:40000/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

启动容器命令如下:

docker run -d --restart=always --name nginx -v E:\DockerMapping\nginx/nginx.conf:/etc/nginx/nginx.conf -v E:\DockerMapping\nginx/www/:/usr/share/nginx/html/ -v E:\DockerMapping\nginx/logs/:/var/log/nginx/ -v E:\DockerMapping\nginx/conf/:/etc/nginx/conf.d -p 80:80 -p 443:443 --privileged=true nginx:1.25.1

此时,浏览器访问 yourdomain.com,将看到nginx首页,访问 httpbin.yourdomain.com,将看到nginx首页。

4 总结

其实后端开发的同学应该知道,这种方式就是很常见的后端架构,我们可以基于这种架构在本地搭建一个服务集合。其他小伙伴应该也能通过这个教程了解一下后端请求分发流程。

还有两点可以继续优化的地方:

  1. 可以自定义nginx首页,让首页变成一个面板,指向其他服务,对用服务比较多的同学就方便很多了。
  2. 我们可以使用自签证书,让访问支持https。如何制作服务器证书并完成服务器配置可以参考这篇文章:自签CA并完成Nginx HTTPS配置