Docker的介绍就不多说了,知乎简书思否CSDN一堆一堆的
1. 安装环节
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# docker 的三大组件:docker-ce、docker-ce-cli、containerd.io
# --nobest不只使用最佳选择的软件包 --skip-broken跳过无法安装的软件包
yum install -y docker-ce docker-ce-cli containerd.io --nobest
复制代码
2. 镜像制作环节*(可以直接不看,因为本次是热部署,可以不打包镜像)
之所以写这个镜像制作环节,是因为制作镜像时可以通过配置Dockerfile指定启动容器时执行的命令和操作,相比 3 中的完全简单做个映射是方便不少的
看法
- 镜像可以认为是一整套开发环境的打包,我们通常把一整个开发环境、软件打包,然后用于构建去使用这个包内信息构建全新的环境。例如,传统虚拟机安装操作系统时需要使用的操作系统镜像.iso文件,小小的镜像内就包含了生成一个完整操作系统全部必要信息
- docker镜像+容器 vs conda虚拟环境:
- docker的职能范围其实比conda大不少,因为docker自己制作镜像时能干的事情显然比conda多——docker是可以打包整个操作系统环境的!操作起来和打包其他东西没什么区别,有的linux系统镜像(alpine)甚至只需5MB就可以利用主机自己的内核直接跑起来,已经是把传统虚拟机模式吊着锤了。相比之下conda虚拟环境使用方便的情景仅限于运行在一台主机
- 从镜像获取方面,其实两者差别不大。如果你只希望在一个主机上跑不同版本的软件环境,这两者根本没啥区别。包括本文,其实conda在这种课题上操作起来反而是比Docker方便的
- docker容器只要启动了就可以一直挂着,对docker来说容器内的事情应当在容器内用shell解决。但conda本身就处于外部命令行环境,不使用setsid的话,一旦与终端连接断开,正在运行的程序就直接GG
- docker在跨系统层面的调用上是有明显优势的,笔者部署时也试过同时部署后端和数据库,这些都是要同时互相调用的,真的,用Docker模拟跨主机访问调用简直不要太方便
项目结构展示
└── project(这里是项目文件夹根目录)
├── Dockerfile
├── README.md
├── config-overrides.js
├── package-lock.json
├── package.json
├── public
└── src
├── App.css
├── App.jsx
├── components
│ ├── Header
| ├──......
│ └── concept graph
├── index.css
├── index.js
├── pages
│ ├── Home
│ ├── ......
│ └── User
├── static
│ ├── img
│ └── steps
└── urlSettings.js
复制代码
Dockerfile
一般的大佬好像很喜欢用nginx做负载均衡,所以往往是依赖于一个docker nginx镜像去生成自己的项目。不过这往往是已经到项目发布的环节,已经不需要再对整个项目做什么改动就上线了(nginx这时候当然就显得很重要啦)
但是上文也说了,我们打算使用热部署,依旧处于开发阶段的。所以本文就是单纯的项目镜像+容器制作教程
编写前,请确保Docker已有镜像:node:alpine,node版本自定,笔者用的是node 16,没装的话执行docker pull node:alpine
就行。(或者干脆不执行,反正Docker是智能识别语句会自动装的)
乞丐版Dockerfile
# 声明依赖哪些已有的环境
FROM node:16-alpine
# 声明作者
LABEL maintaner="iwzbjmf"
# 声明镜像内是否需要当前根目录的文件,目前的做法是把当前目录拷贝到容器的/kg目录下
COPY ./ /kg
# 声明容器内执行命令时的根目录为/kg
WORKDIR /kg
# 声明构建容器时需要执行的命令,由于上文指定了工作目录,所以npm命令会默认在/kg内执行
RUN npm install
# 开放容器8080端口
EXPOSE 8080
# 声明今后在容器启动时自动执行的命令
CMD ["npm","start"]
复制代码
创建镜像
docker build -t 随便起个名字:随便写个版本 .
复制代码
等待执行完成...查看镜像是否已生成
docker images
复制代码
此时就可以看到镜像生成好了,以笔者为例,生成了一个kg-ui:v2的镜像
将镜像放入容器
docker run -itd -v /mnt/web-app/kg:/kg --name newKG -p 8905:8080 kg-ui:v2
复制代码
这一段命令分为以下几个方面:
- docker run -itd
参数 | 意义 |
---|---|
-i | 以交互模式运行容器,通常与 -t 同时使用; |
-t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用; |
-d | 后台运行容器,并返回容器ID; |
-
-v /mnt/web-app/kg:/kg
/mnt/web-app/kg是我项目的绝对路径,/kg是容器内的工作路径,现在将把整个项目目录直接以映射的方式放在容器对应目录里。(COPY命令此时显得没啥必要了)
-
--name newKG
给容器起名字
-
-p 8905:8080
端口映射,可有可无。容器内是完全一套新虚拟环境,完全独立于主机的一套端口。我的项目启动后运行在容器的8080端口,我打算开放主机的8905端口。
-
kg-ui:v2
使用这个镜像!刚刚才做好的,现在就是把镜像放进容器
启动容器
docker start newKG
复制代码
其他命令 (以我的newKG为例)
-
查看当前所有容器状态:
docker ps -a
-
进入容器内部:
docker exec -it newKG sh
(因为使用的是alpine。如果是其他虚拟环境,这里写/bin/bash
)
3. 完全靠挂载解决
提前声明,这种方式还不如直接用conda
无需编写Dockerfile
docker run -itd -v /mnt/web-app/kg:/kg --name newKG -p 8905:8080 node:16-alpine
复制代码
生成容器后,由于没有默认的工作路径,如果日后有改动需要不能直接去使用docker exec -it newKG npm install xxx
,因为npm在根目录下是不允许这么干的,会报ideaTree Track
的错误!
如果想使用虚拟环境内部的npm版本执行命令安装什么东西,或者干别的事情的话,使用如下指令:
docker exec -it newKG npm sh -c "cd kg;npm install xxx"
docker exec -it newKG npm sh -c "cd kg;npm start"(再举个例子。。。因为这种容器不是镜像,docker start后不会自动启动项目的)
复制代码
好了,解决了
4. 参考链接
【Docker安装参考链接】:
Linux下Docker的安装及使用 - 羊37 - 博客园 (cnblogs.com)
Docker 部署 React 全栈应用 - SegmentFault 思否
【docker node版本参考】: