前言:

此为总结之前的学习笔记,我将接收如何在 docker 容器中使用 nginx 反向代理两个项目到一个端口下,并同时将 mysql 的端口通过 nginx 代理出去

安装 nginx
  • 拉取最新的 nginx 镜像docker pull nginx:alpine

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx配置文件路径

  • 查看拉取的镜像docker images

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx代理telnet端口_02

  • 运行容器docker run --name g-nginx nginx:alpine

解释:
--name 启动容器的别名(便于后期管理)
nginx:alpine 指定镜像(apline是一个精简的centos版本,会使镜像提交大大减小)

  • 查看容器运行情况docker ps

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx配置文件路径_03

  • 查看自定义网络docker network inspect g-net

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx代理telnet端口_04

  • 浏览器中访问 http://ip:81 便可查看是否成功

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx代理telnet端口_05

这就安装完成了?当然不是,要知道nginx里的配置可是经常修改的因此我们要将nginx的配置文件挂载到宿主机目录下,便于修改配置
  • 在宿主机中创建配置文件路径mkdir -p /root/nginx/{conf,html,logs}

如何修改容器的inspect配置 容器 修改nginx配置文件_nginx代理telnet端口_06

  • 将我们刚刚创建容器中的默认配置文件拷贝到宿主机中docker cp g-nginx:/etc/nginx/nginx.conf /root/nginxdocker cp g-nginx:/etc/nginx/conf.d/default.conf /root/nginx/confdocker cp g-nginx:/usr/share/nginx/html/index.html /root/nginx/html

为什么我要这样做:
因为 nginx 启动时要加载配置文件,如果直接将配置文件挂载到宿主机下的话,将无法启动 nginx 因此我们要创建默认的配置文件解释:
cp 命令代表复制
g-nginx nginx容器的名字
前面的路径是容器路径,后面的路径是宿主机的存放路径
操作后我们就可以在宿主机目录中看到配置文件了

  • 移除移除容器
    停止容器: docker stop g-nginx移除容器: docker rm g-nginx
  • 重新运行nginx容器,并指定挂载目录docker run -d --name g-nginx -p 81:81 -p 82:82 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/logs:/var/log/nginx -v /root/nginx/html:/usr/share/nginx/html -v /root/nginx/conf:/etc/nginx/conf.d --privileged=true --network g-net  nginx:alpine

解释:
--name 容器名
-v 挂载目录
-p 81:80  宿主机81端口映射到容器80端口
--privileged=true  容器内部对挂载的目录拥有读写等特权(这样log文件就会写入到宿主机中)
--network g-net  容器加入g-net网络
nginx:alpine 镜像! 注意我为啥要加入到容器的自定义 network 网络(可以自己查如何创建自定义网络并将容器加入到自定义网络),因为我的所有容器都通过 network 网络进行容器间的通信,所有容器只有 nginx 对外暴露端口,所有容器统一通过 nginx 进行反向代理自定义网络:
创建:docker network create 自定义网络名
删除:docker network rm 自定义网络名
查看网络的连接情况:docker network inspect 自定义网络名
将已有容器加入到自定义网络:docker network connect 自定义网络名 容器名
在创建容器时加入到自定义网络:在容器名前加上 --network 自定义网络名 就像上面演示的一样

  • 查看运行的容器docker ps
修改 nginx 的配置文件进行反向代理
  • 修改配置文件
    在conf文件夹里新建一个 XXX.conf 文件(随意命名)删除默认的 default.conf
    当然也可以直接在 default.conf 下改
    配置web项目(nuxt和springboot)反向代理
server {
    listen 80;  # 容器的端口
    server_name 自己域名;    # 把域名替换成你自己的
    location /api/ {
        proxy_redirect off;  
        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_pass http://g-springboot:8080/; # 这里设置你要代理的ip+端口,如果你使用了容器的自定义network这ip自己写为容器名称,像我的spring boot 项目容器名为g-springboot并加入了自定义network,使用http://ip:端口/api/即可访问项目
    }
    location / {
        proxy_redirect off;  
        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_pass http://g-nuxt:3000; # 使用http://ip:端口/即可访问项目
    }
}

解释:

一个location就代理了一个项目,其中我的springboot项目在访问时加入了api前缀来区分,并且要注意 /api/  http://g-springboot:8080/  的格式,代理的网址后加了 "/"
这样就成功将两个项目通过nginx反向代理到了nginx容器的80端口下,而nginx容器的80端口又映射到了宿主机的81端口,因而访问 http://ip:81 即可访问 nuxt 项目,即下面的项目, 访问 http://ip:81/api 即可访问到spring boot 下面,即上面的项目

这样就完成了?当然不是,我们还有 mysql 我要是想要远程访问呢,我说了所有容器我只暴露了nginx 的端口,即 mysql 我们也要通 nginx代理出去,当然 mysql 我们就使用82端口了
  • 修改 nginx.conf 配置文件
    在最后面加上
stream {
    server {
        listen 82;  # 映射容器端口
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass g-mysql:3306;  # mysql容器名和端口号
    }
}
  • 当然还有最后一步
    刷新 nginx 的配置,让我们修改的配置生效
    进入 nginx 容器内部:docker exec -it nginx容器名 sh注意是 sh 而不是 bash 因为使用的是 alpine 版本的镜像还记得吗
    然后执行:nginx -s reload完成