上一篇两遍已经完成了MongoDB的搭建,下一步就是EggJS项目的Docker部署。这里会提供2个方式部署实现
- EggJS 工程单独Docker部署 如果你的数据库不在同一个Docker环境下面,只需要单独打包部署EggJS工程。
- 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
。
{
...
"scripts": {
"start": "egg-scripts start --title=egg-server-service",
...
},
...
}
JS工程就可以直接镜像下一步构建镜像。
但如果是 TS工程 打包运行,就会出现这个 500 错误
根据 EggJS 官网的关于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了
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 出现报错等。如果对docker
和eggjs
有足够多的了解,实现起来应该会很顺利,大家如果动手时遇到困难可以留言。