学习

如何使用 Nginx、Docker 和 Redis 构建和运行 Node.js 应用程序

Ajeet Raina
作者
Ajeet Raina, 前 Redis 开发者增长经理

感谢 Node.js - 数百万为浏览器编写 JavaScript 的前端开发人员现在能够编写服务器端代码以及客户端代码,而无需学习完全不同的语言。Node.js 是一种免费的、开源的、跨平台的 JavaScript 运行时环境。它能够处理单个服务器上的数千个并发连接,而不会引入管理线程并发的负担,这可能是错误的重要来源。

在本快速入门指南中,您将了解如何使用 Nginx、Redis 和 Docker 构建 Node.js 应用程序(访问者计数器)。

你需要什么?#

  • Node.js: 一种开源的、跨平台的、后端 JavaScript 运行时环境,它运行在 V8 引擎上并在 Web 浏览器之外执行 JavaScript 代码。
  • Nginx: 一种用于 Web 服务器、反向代理、缓存、负载平衡、媒体流等功能的开源软件。
  • Docker: 一种用于开发、交付和运行应用程序的容器化平台。
  • Docker Compose: 用于定义和运行多容器 Docker 应用程序的工具。

项目结构#

.
├── docker-compose.yml
├── redis
├── nginx
│   ├── Dockerfile
│   └── nginx.conf
├── web1
│   ├── Dockerfile
│   ├── package.json
│   └── server.js
└── web2
    ├── Dockerfile
    ├── package.json
    └── server.js

先决条件:#

– 安装 Docker Desktop

使用 Docker 的安装指南 在您的本地系统上设置 Docker Desktop for Mac 或 Windows。

信息

Docker Desktop 默认情况下安装了 Docker compose,因此您无需单独安装它。

步骤 1. 创建 Docker compose 文件#

使用以下内容创建一个空文件,并将其保存为“docker-compose.yml”

version: '3.9'
services:
  redis:
    image: 'redis:alpine'
    ports:
      - '6379:6379'
  web1:
    restart: on-failure
    build: ./web
    hostname: web1
    ports:
      - '81:5000'
  web2:
    restart: on-failure
    build: ./web
    hostname: web2
    ports:
      - '82:5000'
  nginx:
    build: ./nginx
    ports:
    - '80:80'
    depends_on:
    - web1
    - web2

compose 文件定义了一个包含四个服务的应用程序 redis, web1, web2 和 nginx。在部署应用程序时,docker-compose 将 Web 服务容器的端口 80 映射到主机上的端口 80,如文件中所述。

信息

默认情况下,Redis 在端口 6379 上运行。请确保您不在系统上运行另一个 Redis 实例,或者主机上的端口 6379 未被其他容器使用,否则应更改端口。

步骤 2. 创建 nginx 目录并添加以下文件:#

文件:nginx/nginx.conf

upstream loadbalancer {
  server web1:5000;
  server web2:5000;
}

server {
  listen 80;
  server_name localhost;
  location / {
    proxy_pass https://loadbalancer;
  }
}

文件:Dockerfile

FROM nginx:1.21.6
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf

步骤 3. 创建一个 web 目录并添加以下文件:#

文件:web/Dockerfile

FROM node:14.17.3-alpine3.14

WORKDIR /usr/src/app

COPY ./package.json ./
RUN npm install
COPY ./server.js ./

CMD ["npm","start"]

文件:web/package.json


  "name": "web",
  "version": "1.0.0",
  "description": "Running Node.js and Express.js on Docker",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.17.2",
    "redis": "3.1.2"
  },
  "author": "",
  "license": "MIT"
}

文件:web/server.js

const express = require('express');
const redis = require('redis');
const app = express();
const redisClient = redis.createClient({
  host: 'redis',
  port: 6379
});

app.get('/', function(req, res) {
    redisClient.get('numVisits', function(err, numVisits) {
        numVisitsToDisplay = parseInt(numVisits) + 1;
        if (isNaN(numVisitsToDisplay)) {
            numVisitsToDisplay = 1;
        }
        res.send('Number of visits is: ' + numVisitsToDisplay);
        numVisits++;
        redisClient.set('numVisits', numVisits);
    });
});

app.listen(5000, function() {
    console.log('Web application is listening on port 5000');
});

步骤 4. 部署应用程序#

让我们使用 docker-compose 部署完整的应用程序

$ docker-compose up -d
Creating nginx-nodejs-redis_redis_1 ... done
Creating nginx-nodejs-redis_web1_1  ... done
Creating nginx-nodejs-redis_web2_1  ... done
Creating nginx-nodejs-redis_nginx_1 ... done

预期结果

列出正在运行的容器。您应该看到三个容器正在运行,以及以下端口映射

docker-compose ps
           Name                        Command              State           Ports
------------------------------------------------------------------------------------------
nginx-nodejs-redis_nginx_1   /docker-entrypoint.sh ngin     Up      0.0.0.0:80->80/tcp
                             ...
nginx-nodejs-redis_redis_1   docker-entrypoint.sh redis     Up      0.0.0.0:6379->6379/tcp
                             ...
nginx-nodejs-redis_web1_1    docker-entrypoint.sh npm       Up      0.0.0.0:81->5000/tcp
                             start
nginx-nodejs-redis_web2_1    docker-entrypoint.sh npm       Up      0.0.0.0:82->5000/tcp
                             start

步骤 5. 测试应用程序#

应用程序启动后,导航到 https://localhost 在您的 Web 浏览器中,或运行:

curl localhost:80
curl localhost:80
web1: Total number of visits is: 1
curl localhost:80
web1: Total number of visits is: 2
$ curl localhost:80
web2: Total number of visits is: 3
$ curl localhost:80
web2: Total number of visits is: 4

步骤 6. 监控 Redis 键#

如果要监控 Redis 键,可以使用 MONITOR 命令。在您的 Mac 系统上使用 brew install redis 安装 redis-cli ,然后通过发出以下命令直接连接到 Redis 容器:

% redis-cli
127.0.0.1:6379> monitor
OK
1646485507.290868 [0 172.24.0.2:34330] "get" "numVisits"
1646485507.309070 [0 172.24.0.2:34330] "set" "numVisits" "5"
1646485509.228084 [0 172.24.0.2:34330] "get" "numVisits"
1646485509.241762 [0 172.24.0.2:34330] "set" "numVisits" "6"
1646485509.619369 [0 172.24.0.4:52082] "get" "numVisits"
1646485509.629739 [0 172.24.0.4:52082] "set" "numVisits" "7"
1646485509.990926 [0 172.24.0.2:34330] "get" "numVisits"
1646485509.999947 [0 172.24.0.2:34330] "set" "numVisits" "8"
1646485510.270934 [0 172.24.0.4:52082] "get" "numVisits"
1646485510.286785 [0 172.24.0.4:52082] "set" "numVisits" "9"
1646485510.469613 [0 172.24.0.2:34330] "get" "numVisits"
1646485510.480849 [0 172.24.0.2:34330] "set" "numVisits" "10"
1646485510.622615 [0 172.24.0.4:52082] "get" "numVisits"
1646485510.632720 [0 172.24.0.4:52082] "set" "numVisits" "11"

进一步参考资料#