前言
本文内容包括:linux服务器安装Docker、使用Docker部署node.js应用、更新、Docker里连接主机的mysql数据库,以及可能用到的Docker命令。
网上也有不少类似的文章,但有的过于简单甚至有误,不太适合新手。通过参看多篇文章,并基于使用Docker部署egg.js应用的实践经验整理出了本文。
1:Docker的前端应用场景是什么?
每个node.js应用需要放在一个独立的环境Docker容器内运行,相互隔离,互不影响。
2:Docker部署node.js应用的优点是什么?
使用Docker容器部署node.js快速方便,特别是应用较多时部署迁移等使用Docker会更方便。
3:为什么要使用Docker部署eggjs应用?
在同一台服务器上不能同时运行多个eggjs应用,除非停止另外一个eggjs应用。
4:使用Docker部署node.js应用,大体的流程是什么样的?
-> 服务器安装好Docker
-> 本地应用根目录编写好`Dockfile`文件
-> 将整个应用一起上传到服务器目录下
-> 使用终端连接服务器执行命令安装Docker
-> 部署成功。具体的操作请看下文。
服务器安装Docker
如果要使用Docker,需使用Centos 7.x版本。Docker对内核要求比较高,要在Centos6.5及更高的版本的64位系统里安装,网上说6.x使用Docker会有不稳定情况。本文安装docker ce
版本。
1. 安装一些系统依赖:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
2. 添加软件源,这里使用阿里的源,更快更稳定:
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3. 更新 yum
软件源缓存,并安装 docker-ce
:
sudo yum makecache fast
sudo yum install docker-ce
4. 启动docker-ce
:
sudo systemctl enable docker
sudo systemctl start docker
5. 查看Docker版本:
docker -v
本人在Centos 7.2上安装的Docker版本为18.05.0-ce。
关于docker
的使用等可查看 非官方docker中文版文档。
部署node.js应用到服务器
1. egg.js应用需要修改根目录下的package.json(普通node.js应用可忽略这一步):将start
这行里命令里的--daemon
去掉,即启动eggjs使用egg-scripts start
就好了。在Docker里eggjs应用要在前台运行。
2. 在本地应用的根目录下(package.json所在目录)新建一个名为Dockerfile
的文件(无后缀),将以下内容复制到文件里,并将/usr/src/node-app/koa-server
全部替换为你想设置的路径(该路径为docker容器里的路径,可自行设置):
# 设置基础镜像,如果本地没有该镜像,会从Docker.io服务器pull镜像
FROM node:8.6.0-alpine
# 设置时区
RUN apk --update add tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk del tzdata
# 创建app目录
RUN mkdir -p /usr/src/node-app/koa-server
# 设置工作目录
WORKDIR /usr/src/node-app/koa-server
# 拷贝package.json文件到工作目录
# !!重要:package.json需要单独添加。
# Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。
# 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。
COPY package.json /usr/src/node-app/koa-server/package.json
# 安装npm依赖(使用淘宝的镜像源)
# 如果使用的境外服务器,无需使用淘宝的镜像源,即改为`RUN npm i`。
RUN npm i --registry=https://registry.npm.taobao.org
# 拷贝所有源代码到工作目录
COPY . /usr/src/node-app/koa-server
# 暴露容器端口
EXPOSE 9002
# 启动node应用
CMD npm start
上面的注释一目了然。整个过程简单描述就是:1.拉取docker镜像(并设置时区等);2.创建docker工作目录,并将package.json拷贝到docker里;3.安装npm依赖;4.将服务器上的应用拷贝到docker里;5.暴露docker容器的端口,然后启动node应用。
3. 使用ftp工具或git工具将整个应用上传到生产环境服务器,并使用终端连接到服务器,进入到服务器应用的目录下;(过程略)
4. 执行以下命令,安装docker镜像;
sudo docker build -t node/koa-server .
-t
是对该镜像进行tag标识,标识的名字为node/koa-server
,可以自定义这个名字。镜像的构建过程依赖于网速,整体还比较快。npm依赖可能会久一些,因为egg.js的依赖比较多。如果所有步骤执行完,会有success的提示,安装成功了。
5. 执行以下命令,使用刚创建好的镜像来启动一个容器;
普通node.js应用
sudo docker run -d --name koa-server -p 9002:9002 node/koa-server
-d
为后台运行容器。如果普通node.js应用使用以上命令,容器使用9002端口,与Dockerfile里面的一致。
eggjs应用
sudo docker run -d --net=host --name koa-server node/koa-server
eggjs应用需要执行以上命令,即增加了--net=host
,该参数表示使用host网络模式与主机共享网络来连接mysql数据库;(暂时使用这种模式成功了,后续研究其他更好方案)。
6. 执行以下命令查看容器是否启动成功;
docker ps
以上命令是查看运行中的容器。如果刚才启动成功,则会显示出来。
curl -i localhost:9002
也可以通过curl命令或者到浏览器里输入应用的访问地址,来查看能否访问应用,如果可以则安装成功。
docker logs containerId
如果刚才执行docker ps
没有看到刚刚启动的容器,说明启动失败,使用该命令来查看启动的具体情况。
7. docker容器里eggjs连接mysql:
只需要根据情况修改数据库相关信息即可,在host网络模式下,容器里eggjs的mysql配置文件里的host仍可设置为localhost
。
更新docker里的node.js应用:
1. 通过查看容器列表,找到需要停止的容器ID;
docker ps
2. 停止容器;
sudo docker stop containerId
3. 删除容器;
sudo docker rm containerId
4. 删除镜像;
# 正常情况可以删除
sudo docker rmi imageId
# 提示无法删除情况下,强制删除
sudo docker rmi -f imageId
5. 将本地应用代码更新到服务器目录下。
6. 按照上面的步骤重新构建镜像和启动容器。
重点总结
- 使用Centos 7.x版本安装docker。
-
--daemon
要去掉,让eggjs应用直接前台运行。 - Dockerfile里先拷贝package.json,安装npm依赖后,再拷贝应用的代码。
- 使用境外服务器则不需要使用淘宝的npm镜像源。
可能出现的问题
- npm安装失败:可能是镜像源的问题,需要删除镜像重新构建镜像。
- 镜像无法删除:需要先停止和删除容器。
其他常用命令
镜像相关:
查看镜像构建工程
sudo docker history node/koa-server
比如上面我们构建node/koa-server
这个镜像后,可以通过这个命令来查看该镜像的构建过程,来发现问题。
查看所有镜像列表
docker images
删除镜像
sudo docker rmi imageId
sudo docker rmi -f imageId
先查看镜像列表,找到要删除的镜像ID,然后使用该命令删除。-f
为强制删除。
容器相关:
查看所有容器列表
docker ps
查看某个容器的信息
docker logs containerId
先查看容器列表,找到要查看容器的ID,然后使用该命令查看。
拷贝主机的文件到容器的目录下
docker cp src/. mycontainer:/target
src
为要拷贝的目录名,mycontainer
为容器的id,target
为目标目录名。
进入某个容器的环境
sudo docker exec -it containerId /bin/bash
或
sudo docker exec -it containerId /bin/sh
先查看容器列表,找到要查看容器的ID,然后使用该命令查看。/bin/sh
可在执行docker ps
后看到。退出容器可以执行exit;
。
转载来源 # Reno
https://beautycss.net/2018/06/06/deploy-eggjs-app-with-docker/