Docker 实战:使用 Nginx 作为容器入口代理 Node 服务

23 阅读4分钟

上一篇介绍了 Docker 的核心思想:

Docker = 应用 + 运行环境

它解决的是:

“我的电脑能运行,你的电脑为什么不能运行?”

实际开发中,一个项目通常依赖很多环境:

Node
Redis
MySQL
React
Next
Nginx

这些服务都有自己的版本要求。

Docker 可以将它们分别封装成独立的运行环境。

例如:

项目

├── Node Container
│
├── Redis Container
│
├── MySQL Container
│
└── Nginx Container

每个服务独立运行,又可以互相通信。

本文通过一个简单 Web 服务,理解 Docker 如何运行 Nginx,并通过 Nginx 代理后端 Node 服务。


1. 一个简单 Web 服务

假设现在有一个 Node 后端服务。

代码:

const express = require("express")

const app = express()

app.get("/", (req, res) => {
    res.send("Hello Docker")
})


app.listen(1314, () => {
    console.log("server running at 1314")
})

启动:

node app.js

服务运行:

localhost:1314

访问:

http://localhost:1314

浏览器可以得到:

Hello Docker

目前请求流程:

浏览器

↓

Node服务

↓

返回数据

2. 为什么需要 Nginx?

如果只是本地开发:

浏览器

↓

localhost:1314

↓

Node

完全没有问题。

但是生产环境中,用户通常不会直接访问:

xxx.com:1314

原因:

  • 用户不应该知道后端端口
  • 不同服务可能运行在不同端口
  • 需要统一入口管理请求

例如:

用户访问:

www.example.com

默认访问:

80端口

但是我们的 Node 服务:

1314端口

所以需要一个中间层:

用户

↓

Nginx :80

↓

Node :1314

这个过程叫:

反向代理(Reverse Proxy)


3. Nginx 做什么?

Nginx 是一个服务器软件。

在这里,它主要负责:

  • 监听用户请求
  • 根据配置转发请求
  • 隐藏后端真实服务地址

例如:

用户访问:

localhost:80

Nginx 根据配置:

location / {

    proxy_pass http://localhost:1314;

}

转发:

localhost:80localhost:1314

用户只知道:

localhost:80

不知道:

Node运行在1314端口

4. 使用 Docker 运行 Nginx

Docker 最大的特点:

不需要手动安装环境。

我们直接使用 Nginx 官方镜像。

拉取镜像:

docker pull nginx

得到:

nginx Image

Image 可以理解为:

一个已经准备好的运行环境模板。

运行:

docker run nginx

Docker 会根据 Image 创建:

nginx Container

Container 才是真正运行的 Nginx 服务。


5. docker run 参数解析

实际运行:

docker run \
--name my-nginx-demo \
-p 80:80 \
-v /Users/shunwuyu/Desktop/ai_doubao_ysw/backend/docker/demo/nginx.conf:/etc/nginx/nginx.conf \
-d nginx

这个命令包含几个重要概念。


5.1 --name:给 Container 命名

--name my-nginx-demo

给创建出来的容器命名:

Container

name:

my-nginx-demo

之后可以通过名字管理:

docker stop my-nginx-demo

5.2 -p:端口映射

-p 80:80

格式:

本机端口 : Container端口

这里表示:

电脑80端口

映射

Nginx Container的80端口

因此:

浏览器访问:

localhost:80

请求进入:

Nginx Container:80

流程:

浏览器

↓

电脑80端口

↓

Docker端口映射

↓

Container 80端口

5.3 -v:挂载配置文件

-v 本机文件:/container文件

例如:

-v nginx.conf:/etc/nginx/nginx.conf

作用:

把电脑上的:

nginx.conf

映射到:

Container内部:

/etc/nginx/nginx.conf

为什么需要?

因为 Nginx 的转发规则需要配置。

我们修改本机:

nginx.conf

Container 中的 Nginx 就会读取新的配置。


5.4 -d:后台运行

-d

表示:

detach

让 Container 在后台运行。

否则:

docker run nginx

终端会一直显示 Nginx 日志。


6. nginx.conf 配置反向代理

例如:

server {

    listen 80;


    location / {

        proxy_pass http://host.docker.internal:1314;

    }

}

含义:

监听:

80端口

如果收到请求:

转发给:

1314端口的Node服务

7. 完整请求流程

现在整个系统:

                 浏览器

                    |


              localhost:80

                    |


          Docker端口映射(-p)

                    |


          Nginx Container

                    |


          nginx.conf配置

                    |


              proxy_pass

                    |


          Node服务:1314

                    |


                返回数据

具体过程:

第一步

用户访问:

localhost:80

第二步

请求进入 Docker:

-p 80:80

将电脑80端口映射到:

Nginx Container:80

第三步

Nginx 接收到请求。

读取:

nginx.conf

发现:

proxy_pass http://host.docker.internal:1314;

第四步

Nginx 将请求转发:

Node服务:1314

第五步

Node 返回结果:

Node

↓

Nginx

↓

浏览器

8. Docker 在这个流程中的作用

这里有两个角色:

Nginx Container

负责:

接收请求

↓

转发请求

Node 服务

负责:

业务逻辑

↓

返回数据

最终结构:

Docker

├── Nginx Container

│       ↓

│   反向代理

│

└── Node服务


    处理业务

9. 运维常用 Docker 命令

查看运行中的 Container:

docker ps

停止所有 Container:

docker stop $(docker ps -q)

删除所有 Container:

docker rm $(docker ps -aq)

删除镜像:

docker rmi nginx

拉取 MySQL:

docker pull mysql:8.0

总结

Docker 解决:

应用运行环境一致的问题。

Nginx 解决:

请求入口和服务转发的问题。

在这个例子中:

用户

↓

localhost:80

↓

Nginx Container

↓

Node服务:1314

Docker 负责运行 Nginx 和 Node。

Nginx 负责把用户请求转发给真正处理业务的服务。

这就是一个最基础的 Docker Web 部署流程。