🎉 8 周年订阅优惠

用 Docker Compose 搭建 Node.js 应用(Nest.js)的本地开发环境

最近同学们在练习中遇到很多问题都跟开发环境有关,虽然开发 Node.js 应用只需要安装一个 Node.js,我也建议大家安装跟练习中同样的版本,但依赖存在大量的变数,因为操作系统不同、网络环境不同、安装的方式不同等等。这些变数导致遇到了各种各样的问题。

很多问题跟权限有关,有位同学试了很多次就是无法创建项目,我通过远程协助,发现问题是因为 npm 的缓存引起的,清除缓存以后,重新再去创建项目就可以了。

如果使用官网下载的安装包安装的 Node.js ,用 npm 在全局范围安装命令的时候就会遇到权限问题,因为在全局安装的这个命令,会存储在系统的某个地方,当前用户对这个地方有可能是没有权限的。解决的方法是使用 NVM 管理在系统上的 Node.js,或者手工通过配置修改 npm 在全局范围安装包的目录,换成对当前用户来说有权限的目录就行了。

虽然问题总会有方法解决,但这并不理想,我们最好可以统一开发学习环境,这样可以更容易排除解决遇到的问题。这个更好的方法应该是用 Docker 来搭建本地开发环境。我们可以使用 Docker 镜像更精准地规范开发学习环境,这样就能降低出现的由于环境引起的各种问题。解决了环境问题,剩下的事情只要细心,尽量不要因为粗心大意而输入错误的代码,就完全可以跟着训练学习了。

我们可以规定开发学习中使用的镜像,这个镜像里面有特定的操作系统、应用环境等等。也就是可以保证所有使用这个镜像提供的环境开发或学习的人都拥有相同的环境。这个镜像可以使用别人做好的,也可以是我们自己制作的。

下面介绍了一套完整的,在本地搭建 Node.js 开发环境的方法,我会用 Nest.js 这个应用框架做演示,因为这是我们近期要学习的一套 Node.js 应用框架。

需求

在本地使用 Docker 可以去安装一个 Docker 桌面版,比如 Docker for Windows 或 Docker for Mac。在 Mac 电脑上使用 Docker 桌面版不会有太大问题,但是在 Windows 上运行 Docker 桌面版会有一些需求。

系统必须是 Windows 10 专业版或企业版,普通的 Windows 10 不行,而且需要在系统里启用 Hyper-V。

准备

下载安装 Docker 桌面版,体积挺大,需要下一会儿,下载之前你需要使用 Docker Hub 帐号登录一下才行。

Docker 的大部分操作需要在命令行界面下完成,所以你需要准备一个命令行界面,macOS 用户可以使用系统自带的终端(Terminal),Windows 用户建议下载安装完整版的 Cmder,然后新建一个 Bash as admin 的命令行。

配置

Docker 在创建容器的时候,需要用到一些镜像,也就是如果你的系统上还没有这些镜像的话,Docker 会自动到一个地方去下载这个镜像,保存在你的电脑上,然后基于这个镜像去创建你需要的容器。

下载这些镜像的地方默认在国外,所以我们在国内有时会比较慢,解决的方法是配置一下 Docker 让它使用国内的镜像加速地址。比如阿里云暂时就提供了这个服务,你可以使用自己的阿里云帐号登录到阿里云的容器镜像服务,在里面你会找到一个镜像加速地址,看起来像这样:https://wgaccbzr.mirror.aliyuncs.com

把你在阿里云容器镜像服务上找到的加速地址,配置到你的 Docker 的 Registry Mirrors 里面。

Nest.js 开发环境

下面我们用 Docker Compose 搭建一个在本地可以运行 Nest.js 应用的开发环境。

docker-compose.yml

Docker Compose 允许我们在一个文件里描述应用需要的服务(容器),为你要开发的项目新建一个目录,然后在根目录下创建一个  docker-compose.yml 文件。里面先添加两行代码:

version: '3'

services:

version 设置了一下要使用 Docker Compose 版本,一会儿开发环境需要的几个服务会在 services 下面定义。

.env

在 docker-compose.yml 文件里定义的服务可以使用一些环境变量,这些环境变量还有对应的值可以单独放在一个叫 .env 的文件里面,这个文件就相当于是一个配置文件。在项目根目录下面创建一个空白的文件叫:.env

准备 Nest.js 应用的命令行工具

你打算开发基于 Nest.js 框架的 Node 应用,可以先去安装这个框架提供的命令行工具(@nestjs/cli),它可以让我们使用命令去创建全新的应用还有应用里需要的一些组件。不过因为我们打算用 Docker 的方式搭建应用的开发环境,所以就不直接在电脑上去安装这个工具了,因为这需要你在电脑上安装 Node.js。

docker-compose.yml 文件里定义一个服务,它的作用就是让我们可以使用 Nest.js 框架里提供的命令行工具,打开 docker-compose.yml 文件,在 services 下面添加一个命令行工具服务:

version: '3'

services:
  cli:
    image: nestjs/cli
    volumes:
      - ./app:/workspace
    tty: true

上面定义了一个叫 cli 的服务,这个名字你可以随便定义,这个服务用的 image,也就是镜像是 nestjs/clivolumes 设置了一下数据卷的功能,意思就是让当前目录下的 app 这个目录,对应容器里的 /workspace 这个位置。把 tty 设置成 true 是为了让这个容器一直运行。

打开系统的终端(Terminal),Windows 用户推荐使用 Cmder。进入到 docker-compose.yml 文件所在的目录,然后运行服务:

cd ~/desktop/ninghao-nestjs
docker-compose up -d cli

上面执行了两条命令,第一行是进入到了 docker-compose.yml 文件所在的目录,第二行命令是在后台运行了在 docker-compose.yml 文件里定义的一个叫 cli 的服务。验证一下服务是否运行:

docker-compose ps
        Name           Command   State    Ports  
-------------------------------------------------
ninghao-nestjs_cli_1   /bin/sh   Up      3000/tcp

注意服务的 State 是 Up 表示正在运行,下面可以登入这个 cli 服务:

docker-compose exec cli /bin/sh

进来以后你的命令提示符会像这样:

/workspace #

在这个容器里我们可以使用 Nest.js 应用里的命令行工具,执行:

nest

会出现一些帮助信息:

Usage: nest [options] [command]

Options:
  -V, --version                                   output the version number
  -h, --help                                      output usage information

Commands:
  new|n [options] [name]                          Generate Nest application
  generate|g [options]  [name] [path]  Generate a Nest element
    Available schematics:

用 Nest 命令行工具创建应用

进入到创建的 cli 这个容器里面以后,可以执行 nest 命令,下面我们用这个命令去创建一个 Nest.js 项目。执行:

nest new app

会出现类似的东西:

⚡  We will scaffold your app in a few seconds..

CREATE /app/.prettierrc (51 bytes)
CREATE /app/README.md (3370 bytes)
CREATE /app/nest-cli.json (84 bytes)
...

上面就是用了 nest new 命令创建了一个项目,放在 app 目录的下面,虽然是在 cli 容器里创建的这个项目,但是我们配置了这个服务的数据卷,所以创建的项目文件也会在本地电脑上看到。也就是你在本地电脑上这个 docker-compose.yml 文件所在的目录的下面,会看到一个 app 目录,这里的东西就是创建的 Nest.js 项目。

在开发应用的时候,如果你要使用 nest 命令行工具生成项目需要的文件,你就可以进入到这个 cli 服务容器里面,然后使用 nest 命令去创建你需要的东西。

创建的项目的时候可能会提示:

Failed to execute command: git init
Git repository has not been initialized

这是因为创建完项目之后,nest 命令会去初始化一个代码仓库,但是在这个容器里并没有安装 git ,所以执行相关命令的时候就会出现问题。你可以在本地用 Git 对项目做源代码管理。

注意如果你觉得创建项目的时候速度慢,可以在进入 cli 服务里面以后,执行一下:

npm config set registry https://registry.npm.taobao.org

定义应用服务

docker-compose.yml 文件里,再定义一个运行 Nest.js 应用的服务:

  nest:
    image: node:${NODE_VERSION}
    working_dir: /home/node/app
    command: npm config set registry https://registry.npm.taobao.org
    command: npm run start:dev
    volumes:
      - ./app:/home/node/app
    ports:
      - ${APP_PORT}:3000

上面定义了一个叫 nest 的服务,因为我们创建的应用是基于 Nest.js 框架的,所以这个服务的名字叫 nest,你也可以换成自己喜欢的名字。

nest 这个服务用的 imagenode,具体的版本用了一个环境变量,NODE_VERSION,这个环境变量还有对应的值要在 .env 文件里设置一下。

working_dir 进入到工作目录,然后执行了两个 command,一个是设置了一下 npm 的安装源,这样以后安装包的时候会快一些,第二个 command 是运行了项目的开发服务。

volumes 设置了数据卷,让当前目录下的 app 这个目录,对应 nest 这个服务容器里的 /home/node/app ,我们在这个服务的这个目录的下面,执行了 npm run start:dev,这也就会运行这个 Nest.js 项目的开发服务。

ports 设置了公开的端口,就是设置一个主机(本地电脑)上的端口,让这个端口对应这个容器里的某个端口。运行了 Nest 应用的开发服务以后,会使用 3000 这个端口提供服务。${APP_PORT} 这里用了一个叫 APP_PORT 的环境变量,具体的值要在 .env 文件里设置一下:

NODE_VERSION=11.13
APP_PORT=3000

注意在 .env 文件里,我们让 APP_PORT 这个环境变量的值等于 3000,也就是公开的端口应该就是 3000:3000,也就是本地电脑上的 3000 端口对应的是这个服务里的 3000 端口。

有了这个新的 nest 服务,要再去运行一下:

docker-compose up -d nest

如果一切正常,打开浏览器,访问 http://localhost:3000,你应该会看到一个 “Hello World”。

以后你需要用 npm install 给项目安装一些 Package 的时候,可以进入到这个 nest 服务里面,使用 npm。进入这个服务可以执行:

docker-compose exec nest bash

定义数据服务

开发 Nest.js 应用支持使用多种不同类型的数据库,需要哪种数据库系统,你就去创建一个对应的服务就行了。比如我要在应用里使用 MySQL 这种数据库,所以可以在 docker-compose.yml 里面,再去定义一个 mysql 服务:

  mysql:
    image: mysql:${MYSQL_VERSION}
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: always
    ports:
      - ${MYSQL_PORT}:3306
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

服务里面用到了一些环境变量,打开 .env ,在文件里去定义这些环境变量还有对应的值:

MYSQL_VERSION=5.7
MYSQL_PORT=3306
MYSQL_DATABASE=nest
MYSQL_USER=nest
MYSQL_ROOT_PASSWORD=root
MYSQL_PASSWORD=password

主要就是设置一下要使用的 MySQL 系统的版本,在本地主机上访问这个数据服务用的端口是什么,还有创建的数据库的名字、用户还有密码是什么。你可以修改 .env 文件里的这些环境变量的值,来改变数据库的配置。

上面会创建一个 5.7 版本的 MySQL,在本地主机上使用这个数据服务用的端口是 3306,数据库系统里会创建一个叫 nest 的数据库,操作这个数据库可以使用 nest 用户,对应的密码是 password,另外设置了一下数据库系统的 root 用户的密码为 root

定义好这个数据服务,需要去运行一下:

docker-compose up -d mysql

查看日志

查看容器里的输出的日志,可以执行:

docker-compose logs --follow

附录

docker-compose.yml:

version: '3'

services:
  cli:
    image: nestjs/cli
    volumes:
      - ./:/workspace
    tty: true
  nest:
    image: node:${NODE_VERSION}
    working_dir: /home/node/app
    command: npm config set registry https://registry.npm.taobao.org
    command: npm run start:dev
    volumes:
      - ./app:/home/node/app
    ports:
      - ${APP_PORT}:3000
  mysql:
    image: mysql:${MYSQL_VERSION}
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: always
    ports:
      - ${MYSQL_PORT}:3306
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

.env:

NODE_VERSION=11.13
APP_PORT=3000

MYSQL_VERSION=5.7
MYSQL_PORT=3306
MYSQL_DATABASE=nest
MYSQL_USER=nest
MYSQL_ROOT_PASSWORD=root
MYSQL_PASSWORD=password

评论

感谢,这个我也尝试一下:)
老师,我一直用手机app看训练营的信息,加入频道得通过聊天记录的链接,点加入才行,在频道列表里没有自动更新。看了下网页版,点小地球图标能直接看到列表。然后就在app里搜索新课程的关键字,可以搜到频道才加入到里面。我试着注销,重新登录,也是刷新不了列表。

温馨提示:docker-compose.yml 文件中第一个cli服务的volumes中有误,应该不是./app:/workspace。不过看到最后,在附录的docker-compose.yml文件中已经修正了。:P

:)

谢谢分享 :)
可我又想知道线上环境的方法。(*^__^*) ……



微信好友

用微信扫描二维码,
加我好友。



微信公众号

用微信扫描二维码,
订阅宁皓网公众号。



240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

11393
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点