[React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql

导航

[react] Hooks

[React 从零实践01-后台] 代码分割
[React 从零实践02-后台] 权限控制
[React 从零实践03-后台] 自定义hooks
[React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql
[React 从零实践05-后台] Gitlab-CI使用Docker自动化部署

[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 - 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend

[源码-vue06] Vue.nextTick 和 vm.$nextTick

[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI

[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数
[深入21] 算法 - 查找和排序

(一) 前置知识

(1) 一些单词

recommend:推荐
approach:靠近,方法
( This is the recommended approach. 这是推荐的方法 )

manually:手动,手工
afterward:然后
attach:附着,重视,固定
( `docker attach 容器ID|容器名称` => 进入容器 )
exec:执行
( execute:执行 )

interactive:交互
backstage:后台
defend:守护
( docker run -it中的 i 就是 interactive的缩写,表示交互式的创建容器 )
( docker run -id中的 d 就是 defend的缩写,表示守护式创建容器,后台运行 )

maintainer:维护者 MAINTAINER

alter: 修改
identify:识别
( alter user 'root'@'%' identified with mysql_native_password by 'root'; )

deny: 否认
destination:目的地
premium:优质的,附加费
( navicat premium )

(2) docker 命令

  • 容器相关
    • 创建打开容器:docker run -itd --name 容器名 --link 被链接的容器id:链接后的别名 -p 主机端口:容器端口 -v 宿主机目录:容器目录 镜像名 /bin/bash
    • docker run -d --name=a --net=host 中的 --net=host 得意思是容器和主机的端口号一致,就不需要指定 -p 了
    • 退出当前容器:docker exit
    • 进入容器docker attach 容器ID|容器名称 注意如果容器已经stop,是不能进入容器的,必须先start
    • 进入容器并执行命令docker exec -it 容器ID|容器名称 执行命令 注意这里用-id的话是看不到运行结果的
    • 启动容器:docker start 容器ID|容器名称
    • 停止容器:docker stop 容器ID|容器名称
    • 暴力停止容器:docker kill 容器ID|容器名称
    • 重启容器:docker restart 容器ID|容器名称
    • 删除容器:docker rm -f 容器ID|容器名称
    • 删除所有容器docker rm -f $(docker ps -qa) -f是强制删除,正在运行的容器也能删除
    • 删除所有镜像docker rmi -f $(docker iamges -qa)
    • 查看容器日志:docker logs 容器ID|容器名称
    • 宿主机拷贝文件到容器docker cp 宿主机文件或目录 容器ID|容器名称:容器目录 注意这两条拷贝命令都是在宿主机上执行的
    • 容器拷贝文件到宿主机docker 容器id|容器名称:目录或文件 宿主机目录 注意这两条拷贝命令都是在宿主机上执行的
    • 端口映射:docker run -it -p 8080:80
    • 提交运行时的容器作为镜像docker commit -a='作者' -m='提交的信息' 运行时容器的ID|名称 新镜像名称
    • !!!!数据卷volume!!!!
      • docker run -it -v 宿主机路径:/容器路径
      • 如果映射的容器中没有映射的文件夹,就会在容器中新建,但是映射的文件不会放入容器的文件夹中
      • -v 后面的路径必须是绝对路径
      • 一个容器可以对应多个数据卷,一个数据胶卷可以被多个容器使用
    • 数据卷容器
      • 我的掘金文章 - 数据卷容器1
    • volume
      • docker run -it -v 宿主机路径:/容器路径
      • 如果映射的容器中没有映射的文件夹,就会在容器中新建,但是映射的文件不会放入容器的文件夹中
      • -v 后面的路径必须是绝对路径
      • 一个容器可以对应多个数据卷,一个数据胶卷可以被多个容器使用
    • 镜像相关
      • 推送镜像到服务器 我的掘金文章
      • 查看远程的所有相关镜像docker search ningx 查看hub上所有的nginx镜像
    • docker镜像加速:在阿里云中搜索 [容器镜像服务] / [镜像加速器]

(3) docker安装mysql并访问

(一) 没做数据卷映射
(1) docker pull mysql,
(2) docker run -d --name mysql7 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=root mysql // 注意这里只能是-d,交互式进入后输入3步会报错
(3) docker exec -it mysql7 /bin/bash // 进入容器
(4) mysql -uroot -proot // 输入用户名,密码,启动
(5) 用 navicat 链接 mysql,会报错链接错误
    解决:
        - show databases;
        - use mysql;
    - select host,user,plugin from user;
        - alter user 'root'@'%' identified with mysql_native_password by 'root';
        - 注意所有的结尾都要加 ; 千万别忘了
(6) 链接数据库后,就可以通过 navicat 新建数据库了
(7) 图解:下面前三张图



(二) 数据卷映射
docker run -d \
--name=mysql_container
-p 3307:3306 \
-v /opt/mysql/conf:/etc/mysql \
-v /opt/mysql/logs:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql



(三) mysql常用命令
(1) show databases; // ------------------------ 查看所有数据库
(2) create database test; // ------------------ 创建test数据库
(3) drop database test; // -------------------- 删除test数据库
(4) use test: // ------------------------------ 使用test数据库
(5) select database(); ------------------------ 当前正在使用的数据库
(5) show tables; // --------------------------- 查看当前数据库中的表
(6) create table test(....); // --------------- 新建test表
(7) drop table test; // ----------------------- 删除test表
(8) exit // ----------------------------------- 退出mysql



(四) 向mysql的某个数据库中导入 ( .sql ) 文件
(1) mysql -uroot -proot 启动数据库
(2) show databases; // 查看所有数据库
(3) select database(); // 查看当前正在使用的数据库
(4) use 数据库名;
(5) source 数据库表的.sql文件路径 (  source F:\workSpace\zhigui\ColdChain-data\coldchain.sql )



(五) mysql相关知识
(1) mysql的默认安装路径 C:\Program Files\MySQL\MySQL Server 8.0
(2) my.ini (mysql的配置文件) 默认路径 C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
    - 具体配置介绍:https://juejin.im/post/6844904184462983181
    - 比如可以修改默认暴露的端口 ( port=3306 )
(3) 表的转入转出
    - 转出:
         - mysql中的表可以通过navicat ( 转储SQL文件 ) 的方式 ( 转出 )
    - 转入:
         - 1. 通过navicat中 ( 运行SQL文件 ) 的方式 ( 导入 ) 表
         - 2. 命令行 use数据库 => source .sql文件路径
1
2
3

(4) 部署egg到远程服务器,并访问mysql

(1) 在远程centos中 git clone egg项目
git clone [email protected]:woow-wu7/7-react-admin-egg.git

(2) 在egg项目根目录下执行:npm install --production

(3) npm run start 
- 问题:此时会报错
- 解决:解决办法在package.json中的script的start命令中加入--ignore-stderr
- 最终:"start": "egg-scripts start --daemon --title=egg-server-7-react-admin-egg --ignore-stderr"
- ignore-stderr 是忽略标准错误的意思

(4) 
一直跑:npm run start
不跑了:npm run stop

(5) 访问链接mysql
config.mysql = {
    client: {
      host: '49.233.****',
      port: '3308',
      user: 'root',
      password: '****',
      database: '7-react-admin-egg',
    },
    app: true,
    agent: false,
  };
  
(6) egg项目部署后的默认端口是 7001

(7) 测试
posman跑一下:http://49.233.****:7001/api/table-list

(二) Dockerfile

(1) docker build

docker build -f Dockerfile文件的路径 -t 镜像名:标签名 .

  • 例如:

    • docker build -f /root/work/7/dockerfile/7-web-dockerfile -t nginx .
    • docker build -f $(pwd)/7-web-dockerfile -t mysql .
    • docker build --target node --build-arg NAME=woow -f Dockerfile -t tomcat .
  • 这里要注意后面的 . 是一个有空格的. 这个 ( . ) 的意思是指定 ( 镜像构建过程中的上下文环境的目录 )

  • 说明:

    • 新建好Dockerfile文件后,需要用 docker build 生成镜像
    • docker buid 命令参数大全
      • -f 是file的缩写,docker build -f 用来指定dockerfile的文件路径
      • -t 是tag的缩写,docker build -t 用来指定生成的镜像的名字和标签
      • 一定要注意 docker build 最后面要一个有空格的 .
      • --build-arg=<参数名>=<值>,用来覆盖dockerfile中通过ARG指定的环境变量,将变量覆盖掉
      • --target=,用来明确的指定需要构建的target,比如docker build --target node --build-arg NAME=woow -f Dockerfile -t tomcat .
  • 注意:

    • $(pwd) 一定要加括号,不能写成 $pwd
    • 因为 . 表示的是上下文环境,所以一般执行Dockerfile时,都进入到Dockerfile文件所在的目录中,.就相当于Dockerfile所在的目录了,这个一定得注意

(1.1) ARG => docker build 在有 [ARG] 的情况

  • dockerfile中的 ( ARG ) 表示环境变量,和 ( ENV ) 类似
    • ARG在build镜像时存在,在容器运行时不再存在,而ENV在容器运行时还是存在
  • ARG在dockerfile具体的说是定义 ( 参数名称或者说默认值 )
    • 默认值可以在 docker build --build-arg=<参数名>=<值> 来覆盖
  • 参考链接

(1.2) FROM ... as ...

  • FROM node as node
  • FROM nginx as nginx
  • 如果直接 docker build --build-arg NAME=woow -f Dockerfile -t tomcat .
    • 将生成两个镜像
  • 如果通过 docker build --target node --build-arg NAME=woow -f Dockerfile -t tomcat .
    • 则只会生成 node 镜像
    • --target node 用来明确的指定需要构建的target
ARG NAME=woow_wu7

FROM tomcat as tomcat

RUN echo $NAME

CMD ['cheo', '$NAME']

FROM redis as redis

// docker build --target tomcat --build-arg NAME=woow -f Dockerfile -t tomcat .

(2) Dockerfile语法

语法 说明
FROM 引用基础镜像 - from
WORKDIR 当前的工作目录,即是进入容器后,默认所在的当前目录
WORKDIR指令为Dockerfile中的任何RUN,CMD,ENTRYPOINT,COPY和ADD指令设置工作目录
如果WORKDIR不存在,它将被创建,即使它没有在任何后续的Dockerfile指令中使用
RUN 在新建镜像时执行的命令 - run
比如 RUN yum -y install Vim 表示用yum来安装 Vim 包
CMD 设置容器启动后默认执行的命令和参数
比如 CMD /bin/bash
- 如果docker run的时候指定了其他CMD命令,Dockerfile中的CMD命令被忽略;如果定义了多个CMD,只有最后一个会执行
- CMD ["/bin/echo","hello docker"]
EXPOSE 暴露端口 - 类似于 docker run -p
MAINTAINER 维护者 - maintainer
name<邮箱或者电话>
LABEL 对镜像的描述,类似于注释 - label
name="xxxx" \
date="xxxx"
ENV 设置容器内的环境变量和常量
在其他地方通过 ( $ ) 来引用该环境变量的值
ARG 定义创建镜像过程中使用的变量,编译成功后不存在。
在运行docker build时,指定--builder-arg为变量赋值。
ENTRYPOINT 设置容器启动时运行的命令
ADD ADD除了COPY还有额外解压功能
COPY 拷贝文件,注意推荐使用copy,因为add不能拷贝 tar 文件

(3) docker使用中遇到的坑

  • docker exec
    • docker exec -it node npm -v 会执行命令,但不会进入容器
    • docker exec -it node npm -v /bin/bash 会执行命令,但也不会进入容器
    • docker exec -it node /bin/bash 会进入容器
  • docker run --link 被链接的容器id:链接后的别名

(三) 初级 - 常规部署 react + egg + mysql

(一) 部署mysql
先安装,远程centos系统通过docker安装mysql,(如果不通过docker安装,环境配置麻烦而繁琐)
1. docker pull mysql // ---------------------------------------------------------------------- 拉取镜像
2. docker run -d --name=mysql_c1 -p 3300:3306 -e MYSQL_ROOT_PASSWORD=root mysql // -------- 新建容器
    - ( -e ) 是env环境变量的缩写,表示环境变量
    - msql的默认端口是3306
    - 注意这里只能是通过 (-d) 后台运行,不然会报错,上面有说
3. docker exec -it mysql_c1 /bin/bash // -------------------------------------------------- 进入容器bash环境
4. mysql -uroot -proot // ----------------------------------------------------------------- 输入用户名和密码
5. 利用 navicat 链接数据库
    - 新建链接 - MySQL - 输入连接名,主机,端口,用户名,密码 - 测试链接
    - 报错: access denied for user root@localhost
    - 解决:
       - show databases;
        - use mysql;
    - select host,user,plugin from user;
        - alter user 'root'@'%' identified with mysql_native_password by 'root';
        - 注意所有的结尾都要加 ; 千万别忘了
6. 再次用 navicat 链接就会成功,链接成功后,即可添加表,设计表等,此时mysql对外暴露的端口就是 3300



(二) 部署egg,并访问mysql
(1) 先在egg项目中配置好mysql的访问配置
     - host:写上远程的centos服务器的ip地址
     - port: 是上面映射的 3300 // --------------------------------------------------- mysql的默认端口 3306 ,映射3300
     - root password database数据库名称
(2) 在服务器中通过 git clone 拉取egg项目代码,当然你需要提前安装好git node等环境
(3) npm install --production
(4) npm start
     - 启动过程会报错
     - 解决:解决办法在package.json中的script的start命令中加入--ignore-stderr
     - 最终:"start": "egg-scripts start --daemon --title=egg-server-7-react-admin-egg --ignore-stderr"
     - ignore-stderr 是忽略标准错误的意思
(5) egg项目部署后的默认端口是 7001 // ----------------------------------------------- egg项目启动的默认端口 7001
(6) 测试
posman跑一下:http://49.233.****:7001/api/table-list     



(三) 部署react
nginx部署react // ----------------------------------------------------------------- nginx的默认端口是 80
(1) npm run build
(2) 用 ( nginx ) 来作为 ( react项目的服务 ) 和 ( 反向代理后端egg接口 )
(3) docker pull nginx
(4) docker run -it --name=nginx_c1 \
    -p 8088:80 \
    -v /root/work/7/nginx/web/build:/usr/share/nginx/html \
    -v /root/work/7/nginx/config/conf.d:/etc/nginx/conf.d \
    nginx
(5) 将打包好的react项目生成的build文件夹拷贝到服务器的 /root/work/7/nginx/web/build 目录
(6) 在/root/work/7/nginx/config/conf.d文件夹中添加 ( default.conf ) 文件来配置nginx
(7) default.conf 内容如下
server {
    listen 80;
    server_name localhost;
    location / {
        root /usr/share/nginx/html; // 静态资源目录
        index index.html index.htm; // 静态资源文件
        try_files $uri $uri/  /index.html; // 根据路径匹配文件
    }
    location /api {
        proxy_pass  http://49.233.215.163:7001; // 反向代理,react中的请求代理到egg服务中
    }
}
(8) 访问服务器地址的8088端口,就能访问到前端的react项目了

(四) 中级 - Dockerfile部署 react + egg + mysql

  • 使用Dockerfile的原因:
    • (1) 因为可以保留配置从而可以重复生成需要的配置
    • (2) 解放生成容器过程中的复杂命令,生成容器时,只需要生成容器名简短的命令
  • 缺点
    • Dockerfile很难实现 docker run -v 的效果,因为Dockerfile中的volume只能指定容器的目录,而在宿主机中是随机生成的
(一) mysql的dockerfile
(1) 编写
FROM mysql
WORKDIR ./
ENV MYSQL_ROOT_PASSWORD root
EXPOSE 3306
(2) 生成镜像
docker build -f ./7-mysql-dockerfile -t mysql_build .
(3) 生成容器
docker run -d --name=mysql_build1 -p 3301:3306 a78d48f2327e
(4) 进入容器
 docker exec -it mysql_build1 /bin/bash
(5) 进入mysql
mysql -uroot -proot
(6) 利用 navicat 链接数据库
- 新建链接 - MySQL - 输入连接名,主机,端口,用户名,密码 - 测试链接
- 报错: access denied for user root@localhost
- 解决:
  - show databases;
  - use mysql;
  - select host,user,plugin from user;
  - alter user 'root'@'%' identified with mysql_native_password by 'root';
  - 注意所有的结尾都要加 ; 千万别忘了
(7) 再次用 navicat 链接就会成功,链接成功后,即可添加表,设计表等,此时mysql对外暴露的端口就是 3300



(二) nginx的dockerfile
- 这里 nginx 和 上面的 myssql 更合理的是要做 docker run -v 这样的数据卷映射
- 而 只在Dockerfile中是很难实现的,所以直接跳到 五 中的 docker-compose

(五) 高级 - docker-compose部署 react + egg + mysql

(1) 安装

1、安装python-pip
yum -y install epel-release
yum -y install python-pip

2、安装docker-compose
pip install docker-compose

待安装完成后,执行查询版本的命令确认安装成功
docker-compose version
spring.dubbo
application.name
registry.port

(2) service 和 project 的区别

  • 服务( service ):一个应用容器
  • 项目( project ):由一组关联的应用容器,组成的完整应用单元

(3) docker-compose常用命令行命令

  • 注意:( docker-compose命令 ) 必须在docker-compose.yml文件所在的路径才可以
docker-xompose -v                                // docker-compose的版本号

docker-compose up                                // 启动所有服务
docker-compose up -d                             // 后台启动所有服务
docker-compose -f ./docker-compose2.yml -d up    // 通过docker-compose2.yml后台启动所有服务 (-f 指定yml文件) (-d后台启动)

docker-compose down                              // 停止和删除up命令启动的容器、网络、卷、镜像

docker-compose images                            // 列出项目中所有镜像
docker-compose ps                                // 列出项目中所有容器
docker-compose start 容器名                 // 启动容器
docker-compose stop  容器名                      // 停止容器
docker-compose restart 容器名                    // 重启容器
docker-compose rm 容器名                         // 删除容器( 删除前需要停止容器 docker-compose stop 容器名|ID )

关键字 含义
version (一级) 指定compose文件的版本args,不可缺少的字段
services (一级) 指定所有的 service
image 指定镜像
container_name 指定容器名
working_dir 指定容器的工作路径,相当于Dockerfile中的WORKDIR,例如:/
注意:这里只能是绝对路径
ports 端口映射,相当于 docker run -p 宿主端口:容器端口
target: 容器端口
published:宿主机端口
缩写:-'3033:30'
注意:这里的写法如果指定 target等时第一个加 - ,具体见下面的实例
volumes 数据映射
缩写:-"../nginx/config/conf.d:/etc/nginx/conf.d"
注意:这里用相对路径指定宿主机路径,即docker-compose.yml所在的文件
environment 设置环境变量,类似于Dockerfile中的 env
例如:- MYSQL_ROOT_PASSWORD=root
command 容器启动后默认执行的命令,相当于 docker exec -it 容器 命令 /bin/bash
depends_on 定义容器启动先后顺序
build 指定包含构建上下文的路径,或作为一个对象
该对象具有 ( context ) , ( Dockerfile ), ( args )
context:指定Dockerfile文件所在的路径
dockerfile:指定Dockerfile文件的名称,默认是Dockerfile
args:Dockerfile在build过程中需要的参数

(4) docker-compose.yml文件

version: "3"
services:
  mysql:
    restart: always
    image: mysql
    container_name: mysql__7
    working_dir: /
    ports:
      - "3333:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=root
  web:
    restart: always
    image: nginx
    container_name: nginx__7
    working_dir: /
    ports:
      - 8888:80
    volumes:
      - "../nginx/web/build:/usr/share/nginx/html"
      - "../nginx/config/conf.d:/etc/nginx/conf.d"
image

项目源码

  • 项目源码
  • 部署效果预览地址

资料

我之前的Docker学习笔记 [部署02] Docker 部署vue项目
centos部署egg时,npm install 报错 https://blog.csdn.net/LimonSea/article/details/106326087
docker-compose安装 https://www.jianshu.com/p/5ba9f9159696
docker-compose部署前后端教程 https://juejin.im/post/6844904130226421774#heading-0

系列
https://www.cnblogs.com/evan-liang/p/12405745.html

命令行
docker-compose常用命令 https://www.cnblogs.com/yyxianren/p/10894708.html

yml
docker-compose.yml文件(完善) https://www.jianshu.com/p/90bf0e231e5a
docker-compose.yml文件(也很完善) https://juejin.im/post/6844903958532587533#heading-26

数据库
docker安装mysql8 https://www.cnblogs.com/zhangshengdong/p/12502608.html
mysql导入.sql文件 https://www.cnblogs.com/kenkofox/archive/2011/01/14/1935422.html

你可能感兴趣的:([React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql)