Docker+MongoDB+EggJS(3):在Docker中部署EggJS工程

449 阅读5分钟

上一篇两遍已经完成了MongoDB的搭建,下一步就是EggJS项目的Docker部署。这里会提供2个方式部署实现

  1. EggJS 工程单独Docker部署 如果你的数据库不在同一个Docker环境下面,只需要单独打包部署EggJS工程。
  2. Docker Compose 的方式, EggJS 与MongoDB一起部署。

我想实现一个脚本打包,部署,和启动前端后台。所以在 docker-compose.yml 中需要配置数据库,后台,前端还有nginx。当然后面这里只会讲到数据库和后台的数据,前端的部分后面再补上。

1. EggJS 工程单独Docker部署

部署前端工程代码肯定已经完成,下面我们直接开始Docker部分的处理。

1)Dockerfile

Dockerfile 其实没有什么好说的,基本上拷贝下来就能用。文件加在工程的根目录下面执行命令构建镜像。

# node镜像
FROM node

# 设置时区
# RUN apk --update add tzdata \
#     && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
#     && echo "Asia/Shanghai" > /etc/timezone \
#     && apk del tzdata

# 这个是容器中的文件目录
RUN mkdir -p /usr/src/app 

# 设置工作目录
WORKDIR /usr/src/app

# 拷贝package.json文件到工作目录
# !!重要:package.json需要单独添加。
# Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。
# 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。
COPY ./package.json /usr/src/app/package.json

# 安装npm依赖(使用淘宝的镜像源)
RUN npm i 
# 使用淘宝的镜像源或者其他源,可根据情况修改 --registry
# RUN npm i --production --registry=https://registry.npm.taobao.org

# 拷贝所有源代码到工作目
COPY . /usr/src/app
# 暴露容器端口
EXPOSE 7001
CMD [ "npm", "start" ]

2)构建与启动

构建前需要移除 start 命令中后台运行的参数 —deamon

image.png

{
	...
	"scripts": {
	    "start": "egg-scripts start --title=egg-server-service",
	    ...
	  },
	...
}

JS工程就可以直接镜像下一步构建镜像。

但如果是 TS工程 打包运行,就会出现这个 500 错误

TS报错

根据 EggJS 官网的关于TS工程的说明

关于TS工程的说明

npm start 不会加载 ts,所以 TS工程只要先npm run tsc 把代码编译成js再 npm start 。因此直接像下面这样加上编译命令就可以了。

{
	...
	"scripts": {
	    "start": "**npm run tsc &&** egg-scripts start --title=egg-server-service",
	    ...
	  },
	...
}

接着运行 docker 命令构建镜像

docker build -t egg-test

镜像构建成功之后,运行启动命令后台就能成功跑起来了

# docker run -p hostPort:containerPort -d --name container_name image_name
docker run -p 7001:7001 -d --name egg-server egg-test

在浏览器中进入 [http://127.0.0.1:700](http://localhost:7001)1 应该能顺利看到下面的Hi,egg了

hi,egg

2. Docker-Compose

因为我希望部署时将能够一个脚本将前端和后台都启动好,因为我选择了docker-compose的方式来将前端,后台和数据库都放在一个配置文件中。

工程目录如下

工程目录 docker-compose.yml 内容入如下

version: "3.9"

name: ch4

services:
  # 感应器数据库
  data_mongodb:
    image: mongo:6.0.3 #对应的docker镜像的名字,可指定版本,如mongo:1.0,不指定则为最新版
    container_name: data_mongodb #docker容器的名字
    restart: always #当docker重启时,容器自动启动。
    environment:
      #容器内部默认的设置
      MONGO_INITDB_ROOT_USERNAME: root #mongo默认的账号
      MONGO_INITDB_ROOT_PASSWORD: root #mongo默认的密码
    ports:
      #容器运行的端口号和对应的容器内部的端口号
      - 27078:27017
    volumes:
      # 数据持久化
      - /Users/mac/docker/mongodb/ch4/data/db:/data/db # 挂载数据文件,根据实际路径修改 :前的路径
      - /Users/mac/docker/mongodb/ch4/data/log:/var/log/mongodb # 挂载日志文件,根据实际路径修改 :前的路径
      - /Users/mac/docker/mongodb/ch4/mongod.conf:/etc/mongod.conf # 挂载配置文件,根据实际路径修改 :前的路径

    command: "--config /etc/mongod.conf"
    networks:
      - ch4_services

  # 应用接口服务
  app_service:
    container_name: app_service
    build:
      context: .
      # !!!
      # dockerfile 需要用相对路径
      dockerfile: ./app-service/Dockerfile
    ports:
      - "7001:7001"
    restart: on-failure
    depends_on:
      - ch4_data_mongodb
    networks:
      - ch4_services

  # 数据采集服务
  data_service:
    container_name: data_service
    build:
      context: .
      # !!!
      # dockerfile 需要用相对路径
      dockerfile: ./data-service/Dockerfile
    ports:
      - "7002:7001"
    restart: on-failure
    depends_on:
      - ch4_data_mongodb
    networks:
      - ch4_services

networks:
  ch4_services:

Dockerfile 中的路径也需要换成相对路径

# node镜像
FROM node

# 设置时区
# RUN apk --update add tzdata \
#     && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
#     && echo "Asia/Shanghai" > /etc/timezone \
#     && apk del tzdata

# 这个是容器中的文件目录
RUN mkdir -p /usr/src/app 

# 设置工作目录
WORKDIR /usr/src/app

# 拷贝package.json文件到工作目录
# !!重要:package.json需要单独添加。
# Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。
# 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。
# !!!!
# 这里也需要相对路径
COPY ./data-service/package.json /usr/src/app/package.json

# 安装npm依赖(使用淘宝的镜像源)
RUN npm i 

# 拷贝所有源代码到工作目
COPY ./data-service /usr/src/app
# 暴露容器端口
EXPOSE 7001
CMD [ "npm", "start" ]

有一点还需要注意,如果你达到的效果跟我一样,后台,数据库都docker中,且它们都在同一个网络下,那么docker mongodb host 必须要换成 docker mongo service name,以上面的 docker-compose 为例

// 本地环境 mongodb host
'mongodb://127.0.0.1:27017/db'

// docker mongodb host
'mongodb://data_mongodb:27017/db'

后面再配合Shell 脚本实现拉取最新代码,一键启动,重新构建或者停止等功能。这篇要讲的很仔细对我来说不太容易,主要因为大部分脚本编写都很简单,难点解决在于实现过程中遇到问题,比如docker网络下mongodb host,eggjs typescript 出现报错等。如果对dockereggjs有足够多的了解,实现起来应该会很顺利,大家如果动手时遇到困难可以留言。

参考文章

juejin.cn/post/704656…

andy6804tw.github.io/2020/07/21/…

blog.tcs-y.com/2018/10/05/…