最近同学们在练习中遇到很多问题都跟开发环境有关,虽然开发 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 帐号登录一下才行。
- Windows:https://docs.docker.com/docker-for-windows/install/
- macOS:https://docs.docker.com/docker-for-mac/install/
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/cli
,volumes
设置了一下数据卷的功能,意思就是让当前目录下的 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
这个服务用的 image
是 node
,具体的版本用了一个环境变量,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里搜索新课程的关键字,可以搜到频道才加入到里面。我试着注销,重新登录,也是刷新不了列表。
5 年 5 个月 以前
温馨提示:docker-compose.yml 文件中第一个cli服务的volumes中有误,应该不是./app:/workspace。不过看到最后,在附录的docker-compose.yml文件中已经修正了。:P
5 年 4 个月 以前
:)
5 年 4 个月 以前
谢谢分享 :)
可我又想知道线上环境的方法。(*^__^*) ……
5 年 4 个月 以前