Linux Docker+React热部署

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的镜像

image.png

将镜像放入容器

docker run -itd -v /mnt/web-app/kg:/kg --name newKG -p 8905:8080 kg-ui:v2
复制代码

这一段命令分为以下几个方面:

  1. docker run -itd
参数 意义
-i 以交互模式运行容器,通常与 -t 同时使用;
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-d 后台运行容器,并返回容器ID;
  1. -v /mnt/web-app/kg:/kg

    /mnt/web-app/kg是我项目的绝对路径,/kg是容器内的工作路径,现在将把整个项目目录直接以映射的方式放在容器对应目录里。(COPY命令此时显得没啥必要了)

  2. --name newKG

    给容器起名字

  3. -p 8905:8080

    端口映射,可有可无。容器内是完全一套新虚拟环境,完全独立于主机的一套端口。我的项目启动后运行在容器的8080端口,我打算开放主机的8905端口。

  4. kg-ui:v2

    使用这个镜像!刚刚才做好的,现在就是把镜像放进容器

启动容器

docker start newKG
复制代码

其他命令 (以我的newKG为例)

  1. 查看当前所有容器状态:docker ps -a

  2. 进入容器内部: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版本参考】:

Node - Official Image | Docker Hub

猜你喜欢

转载自juejin.im/post/7083380023763140622