最近遇到一台机器需要部署两个不同版本node的情况,首先就想起了docker,想必还有其他类似环境问题的情况,需要进行项目隔离,而docker正是用来解决这个问题的。
docker的优势就在于环境隔离,相当于可以在一台机器上切割成若干个子机器,而各个子机器之前互不影响,另外docker搭建的项目迁移很方便,不用重复搭建复杂的环境。
Docker 是一个开源的应用容器引擎,基于Go语言并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
通俗点说,linux机器可以比作一键比较大的船,而docker可以制造若干个集装箱,而这些集装箱都是封闭的,每个集装箱里面都可以装不同的东西。延伸到项目中就是,docker可以制作若干个镜像,而每个镜像中都可以有不同的node、redis、mysql版本等。这样我们就不需要有若干个服务器来兼容这些情况。
镜像:可以把镜像理解成iso文件,众所周知虚拟机可以把iso文件制作成windows系统,镜像就是生成容器的前提,可以根据DockeFile制作而成
容器:容器就类似于集装箱,docker基于镜像可以生成容器,一般容器就是我们服务的环境了,一般node的容器会集成node版本+pm2
搭建docker环境需要依赖Dockerfile文件生成镜像,Dockerfile文件会注入node、pm2等环境配置。
步骤:
编写Dockerfile文件 → 创建镜像 → 推送远程镜像仓库
Dockerfile常用命令:
指令 | 说明 |
FROM | 指明当前的镜像基于哪个镜像构建 |
LABEL | 标记镜像信息,添加元数据 |
ARG | 定义构建镜像过程中使用的变量 |
ENV | 指定环境变量 |
VOLUME | 创建一个数据卷挂载点 |
USER | 指定运行容器时的用户名或 UID |
WORKDIR | 配置工作目录 |
EXPOSE | 容器运行时的端口,默认是TCP |
ADD | 从本地或URL添加文件或压缩包到镜像中,并自动解压 |
COPY | 拷贝文件或目录到镜像中 |
ONBUILD | 创建子镜像时指定自动执行的操作指令 |
STOPSIGNAL | 指定退出的信号值 |
HEALTHCHECK | 配置启动容器如何进行健康检查 |
SHELL | 指定默认 shell 类型 |
RUN | 构建镜像时运行的指定命令 |
CMD | 运行容器时默认执行的命令,如果有多个CMD质量,最后一个生效。 |
ENTRYPOINT | 指定镜像的默认入口命 |
Dockerfile文件内容
# 基础node镜像,以14.15.0的node镜像为基础搭建其他内容
# 基础镜像可以是本地镜像也可以是远程仓库镜像,例:a.com/common/node:14.15.0
FROM node:14.15.0
LABEL author="zuggs"
LABEL email="[email protected]"
# RUN命令可以执行命令,安装pm2及pm2-lograte
RUN npm install pm2 -g
RUN pm2 install pm2-logrotate \
&& pm2 set pm2-logrotate:max_size 10G \
&& pm2 set pm2-logrotate:dateFormat YYYY-MM-DD_HH \
&& pm2 set pm2-logrotate:workerInterval 60 \
&& pm2 set pm2-logrotate:rotateInterval "0 * * * *"
# 运行容器时默认执行命令,建议从外面配置,因为每个项目的pm2脚本可能不一样
# WORKDIR /usr/local/etc/nginx/www/project
# CMD pm2-runtime pm2.json
基于Dockerfile打包镜像
# Dockerfile是上面的配置文件,node_pm2是镜像名称,14.15.0是镜像版本,.代表在当前目录打包
docker build -f Dockerfile -t node_pm2:14.15.0 .
镜像打包完成就可以直接推送到远程仓库了,这样在其他机器就可以直接拉到镜像了
dockerhub: https://hub.docker.com/
推送指令(前提需要登录,docker login ...):
# 在项目中标记镜像,node_pm2是本地镜像名称,docker..node_pm2是远程tag名称,14.15.0是版本号
docker tag node_pm2:14.15.0 docker.zuggs.com/common/node_pm2:14.15.0
# 推送远程
docker push docker.zuggs.com/common/node_pm2:14.15.0
前面已经手动打包好所需的node镜像了,我们只需要在服务器拉取所需要的镜像就好
拉取镜像(不拉取也行,可以在执行时直接选远程镜像,这样在会先拉取镜像):
docker pull docker.zuggs.com/common/node_pm2:14.15.0
基于本地or远程镜像启动容器
docker run -d --name demo_server \
--log-opt max-size=10m --net=host \
-v /usr/local/etc/nginx/www/project:/usr/local/etc/nginx/www/project \
docker.zuggs.com/common/node_pm2:14.15.0 sh -c \
'cd /usr/local/etc/nginx/www/project && pm2-runtime start pm2.json'
docker run 常用参数介绍,全部可参考docker官网run配置
-d 后台运行容器
--name 容器名称
--log-opt 设置日志文件大小和数量配置,可选max-size和max-file
--net 容器网络选项
host:容器使用宿主机的IP和端口,--net=host
container:容器和一个指定的容器共享IP、端口,--net=container:NAME_or_ID
none:该模式关闭了容器的网络功能,--net=node
bridge:默认值,此模式会为每一个容器分配、设置IP等,--net=bridge
-v 目录映射,这个容器就可以访问到该目录,宿主机路径:容器挂载路径
-p 端口映射,选择host模式就不需要做端口映射了,本地端口:容器端口
sh -c 容器启动后执行的脚本,Dockerfile未写CMD配置的可以在这里配置
# 搜索镜像
docker search IMAGE_NAME
# 拉取镜像
docker pull IMAGE_NAME
# 构建镜像
docker build -t tag_name:tag_version .
# 标记镜像
docker tag tag_name:tag_version remote_image:remote_version
# 推送镜像到远程
docker push remote_image:remote_version
# 查看所有本地镜像
docker images
# 删除镜像
docker rmi IMAGE_ID
# 查看所有容器,-a是所有容器,默认只查看运行中容器
docker ps -a
# 运行容器
docker run [options]
# 停止容器
docker stop CONTAINER_NAME | CONTAINER_ID
# 启动容器
docker start CONTAINER_NAME | CONTAINER_ID
# 重启容器
docker restart CONTAINER_NAME | CONTAINER_ID
# 在容器中运行后台任务
docker exec CONATAINER_NAME | CONTAINER_ID [COMMAND]
# 查看容器详细信息
docker inspect CONTAINER_ID | CONTAINER_NAME
# 删除容器
docker rm CONTAINER_ID