背景
之前自己博客网站的node.js服务是使用虚拟机部署的,做服务迁移的时候,相应环境都需要重新安装一遍,十分的麻烦。那么有没有什么方式解决这个问题呢?当然有,答案就是------docker!
什么是docker?
docker是创建和管理容器的一种技术。
那什么是容器呢?容器的功能与虚拟机很近似,都是在一个物理主机上运行多个操作系统的技术。最大的不同之处在于,虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
docker的基本概念
接下来我们来了解下docker的基本概念。
镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可以通过命令或者一些基础镜像,构建自己需要的镜像。
容器
容器可以看作镜像的实体,容器可以被创建、启动、停止、删除、暂停等。
了解了docker的基础知识以后,接下让我们看看怎么使用docker部署node.js服务吧!
如果你要部署docker服务,镜像和容器都是不可或缺的。
docker的安装和启动
首先我们需要安装并启动docker。
我的是阿里云服务器,系统是CentOS。可以执行以下命令安装docker:
arduino
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
其它类型的服务器大家可自行查阅如何安装。
安装后可以验证一下安装是否成功:
shell
[root@iZ8vb55rs42xic2s53uc3yZ ~]# docker -v
Docker version 20.10.5, build 55c4c88
然后启动docker:
shell
systemctl start docker
使用docker部署node.js服务
安装好docker后,就可以使用docker部署node.js服务啦。
前面我们介绍了docker镜像,它是部署服务的前提,那么我们如何制作属于自己服务的镜像呢?答案是使用Dockerfile。
Dockerfile
Dockerfile是由一系列指令和参数构成的文本文件,Docker通过Dockerfile中的指令自动构建镜像。
部署node.js服务需要node.js环境、安装npm依赖包、执行服务启动命令等等。
这些都可以在Dockerfile中编写,然后Docker基于你编写的Dockerfile可以自动构建出node.js服务的镜像。
接下来让我们看看Dockerfile如何编写。
Dockerfile
# 基于node:18基础镜像,这些镜像可以在[官网](https://hub.docker.com/_/node) 查找,你可以选择合适的node.js版本。
FROM node:18
# 将当前文件夹下所有文件复制到镜像的/docker/blog-server目录中
COPY . /docker/blog-server
# 设置工作目录
WORKDIR /docker/blog-server
# RUN可以执行一些命令,这里我们安装了工程的npm依赖包
RUN yarn config set registry https://registry.npmmirror.com
RUN yarn
RUN yarn global add pm2@5.3.1
# 定义对外暴露的端口
EXPOSE 3000
# CMD为程序启动命令,我们使用了pm2启动服务,它可以为应用提供进程守护。这里是pm2的启动命令写法,如果你使用其他启动方式,可以进行修改。
CMD ["pm2-runtime", "--json", "pm2.json", "--env", "production"]
构建镜像
有了Dockerfile,镜像构建只需一行docker命令即可:
shell
docker build -t blog-server:latest .
这里的blog-server:latest是镜像名称:版本号。
执行后,最后几行可以看到如下结果:
shell
Successfully built b3eec25bf4b8
Successfully tagged blog-server:latest
这说明镜像已经构建成功了!
启动容器
前面介绍了容器是镜像的实体,运行好容器后,我们也就完成了node.js服务的部署。
我们执行以下命令就可以基于前面制作好的镜像运行容器了:
css
docker run --name=blog-server -it -d -p 3000:3000 blog-server:latest
这里我们基于前面制作好的blog-server:latest镜像生成了一个名为blog-server的容器,它的端口映射是3000。
我们测试一下:
bash
curl http://127.0.0.1:3000/blog/v1/user/info
{"code":1,"message":"success","data":{},"pageSize":1,"pageCurrent":1,"count":1,"isRedirect":0,"redirect":"","login":0}
可以看到接口已经访问通了,我们的node.js服务部署完成了!
发布脚本
前面我们虽然成功启动了容器,但整个流程需要执行好几个命令,还是很不方便。为了能够实现一键部署,我们还需要编写一个shell发布脚本,让它自动完成代码更新,旧镜像、旧容器删除,新镜像、新容器构建的整个流程。
shell发布脚本如下:
shell
image_name="blog-server:latest"
container_name="blog-server"
# 代码拉取
git pull origin master
# 镜像构建
docker build -t ${image_name} .
# 停止旧容器
docker stop ${container_name}
# 删除所有停止的容器
docker container prune -f
# 启动新容器
docker run --name=${container_name} -it -d -p 3000:3000 ${image_name}
# 删除所有未使用的镜像
docker image prune -f
执行该shell脚本命令就可以完成一键部署啦,是不是非常的方便!