[部署04][复习] gitlabCI + docker-compose + ssh免密登录 + 最全Dockerfile

499 阅读15分钟

导航

[react] Hooks

[封装01-设计模式] 设计原则 和 工厂模式(简单抽象方法) 适配器模式 装饰器模式
[封装02-设计模式] 命令模式 享元模式 组合模式 代理模式
[封装03-设计模式] Decorator 装饰器模式在前端的应用
[封装04-设计模式] Publish Subscribe 发布订阅模式在前端的应用
[封装05-ElementUI源码01] Row Col Container Header Aside Main Footer

[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
[源码] koa
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 - 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend

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

[源码-react01] ReactDOM.render01
[源码-react02] 手写hook调度-useState实现

[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI
[部署04] [复习] gitlabCI + docker-compose + ssh免密登录 + 最全Dockerfile

[数据结构和算法01] 二分查找和排序
[数据结构和算法02] 回文字符串
[数据结构和算法03] 栈 和 队列
[数据结构和算法04] 链表 和 树

[深入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] 数据结构和算法 - 二分查找和排序
[深入22] js和v8垃圾回收机制
[深入23] JS设计模式 - 代理,策略,单例
[深入24] Fiber01
[深入25] Typescript
[深入26] Drag

[前端学java01-SpringBoot实战] 环境配置和HelloWorld服务
[前端学java02-SpringBoot实战] mybatis + mysql 实现歌曲增删改查
[前端学java03-SpringBoot实战] lombok,日志,部署
[前端学java04-SpringBoot实战] 静态资源 + 拦截器 + 前后端文件上传
[前端学java05-SpringBoot实战] 常用注解 + redis实现统计功能
[前端学java06-SpringBoot实战] 注入 + Swagger2 3.0 + 单元测试JUnit5
[前端学java07-SpringBoot实战] IOC扫描器 + 事务 + Jackson
[前端学java08-SpringBoot实战总结1-7] 阶段性总结
[前端学java09-SpringBoot实战] 多模块配置 + Mybatis-plus + 单多模块打包部署
[前端学java10-SpringBoot实战] bean赋值转换 + 参数校验 + 全局异常处理
[前端学java11-SpringSecurity] 配置 + 内存 + 数据库 = 三种方式实现RBAC
[前端学java12-SpringSecurity] JWT
[前端学java13-SpringCloud] Eureka + RestTemplate + Zuul + Ribbon

复习笔记-01
复习笔记-02
复习笔记-03
复习笔记-04

docker相关

前置知识

2022/07/24 新增

docker 拷贝镜像到其他主机
---

1. docker save -o 要保存的文件名 要保存的镜像
2. 然后就可以通过 ls 看到镜像文件了
3. 拷贝即可

(1) 一些单词

shortcut 快捷键
intellisense 智能感知
hack 砍
pluk 摘
monitor 显示屏

sign in 登入
sign out 登出
sign up 注册

free trial 免费试用 // free自由免费 trial试用 
tender 嫩的 补给船 // Bar Tender
thor 雷神
maintainer 维护者
reference 参考
brew 酿造 冲泡 下载
secure 安全的
directory 目录
male female 男性女性

eigher...or... ...或...
stable release // 稳定版本
rectangle 矩形
dictionary 字典
concepts 概念 观念 // gitlab ci/cd concepts

specific 特有的 // specific runner
shared 共享的 // shared runner
stuck 卡住 难住
rsync 同步 // sync 同步
above 上面
widely 普遍的 广泛的
fingerprint 指纹
agent 代理商 经纪人
optionally 选择性的 任意的
feel free to 可以随便
slug 偷懒
general setting 通用设置
advance 高级设置

owner 所有者
maintainer 维护者
developer 开发者
guest 访客

(2) brew

问题:
- ubuntu中有 apt-get
- centos中有 yum
- 那么 macos 上没有这两个东西,也不能用,怎么办

回答:
- macos中可以安装 brew
- brew就是类似上面的 yum 和 apt-get
- brew 是 酿制 冲泡 下载 的意思

如何安装:
- mocos中如何安装brew ?
- 教程地址:https://www.cnblogs.com/liyihua/p/12753163.html
- 一条命令搞定,亲测可用的
- /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

相关命令:
- brew ------------------ 查看brew是否安装成功
- brew list ------------- 查看利用brew安装的软件列表
- brew search 包名
- brew install 包名

我为什么要安装brew:
- 因为:我要安装 tree 来查看目录结构
- 安装tree:brew install tree

tree命令
- tree [option] [directory]
- tree 选项 目录
- tree -d src ---------- 表示只显示src的 ( 文件夹 ) 的树结构,不包含文件。( d是directory目录的意思 )
- tree -L 1 src -------- 表示遍历文件夹的 ( 层数 ),这里表示只遍历一层。( L是level的意思 )
- tree -L 1 -d src

(3) linux 命令中的一些特殊符号

1 |
- | 表示 ( 管道符 )
- 表示:command1 | command2 的是将command1命令执行的结果作为command2的输入传入
- 例子:ls -s | sort -n 表示按从小到大的顺序输出,-s是size的意思,-n是number的意思

2 ||
- || 表示 ( 分割多条命令 ),前一条命令为真,则后面的命令不会执行,前一条命令为假,则继续执行后面的命令
- 类比:相当于 或 命令
- 例子: [[ 1 -gt 2 ]] || echo b 表示1大于2成立吗?false的话就输出b

3 &
- & 表示同时执行多条命令,不管命令是否执行成功

4 &&
- && 表示可以同时执行多条命令,当碰到执行错误的命令时,将不再执行后面的命令。如果一直没有错误的,则执行完毕
- 理解:可以理解为 && 越多越严格,&不会阻断执行,&&会阻断执行

5 >
- > 表示将内容输出到某个文件中
- 注意:是 ( 覆盖 )

6 >>
- >> 表示将内容输出到某个文件中
- 注意:是 ( 追加 )
- 对比
  - echo 'abc' > test.txt ----------- 将'abc'写入test.txt,原有的内容将被覆盖
  - echo '123' >> test.txt ---------- 将'123'追加写入到test.txt,追加到原有内容的后面

(4) linux 常见命令

1
服务器添加新用户的命令 ( 两个命令 )
- useradd 
  - useradd如果后面不添加任何选项,创建出来的用户默认是三无用户,且该用户无法登录
  - 无目录 无密码 无系统shell
- adduser
  - adduser创建用户,系统会提示创建用户需要的各种信息,跟随系统就能创建完成
  - 添加后,会在 (/home/用户名) 中创建同名文件夹
- 总结
  - adduser适合新手用户,而useradd适合有经验的用户,所以 ( 省事就用adduser )
  - 注意:两种方法添加的用户,在设置密码之前都是不能登录的,所以需要为指定用户设置密码
  
2
- adduser + 用户名 -------------- 添加用户 ( 注意:添加用户后,还不能登录,需要在添加用户后设置密码 )
- passwd + 用户名 --------------- 设置密码
- userdel -r + 用户名 ----------- 删除用户
- cat /etc/passwd -------------- 查看用户
- cat /etc/group --------------- 查看活跃用户 ( 更精简的查看用户 cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1"|"$3"|"$4 }'|more )


mkdir -p ------------------- 递归创建文件夹
mkdir -p a/b 表示先创建a文件夹,然后在a文件夹中创建b文件夹。这里需要注意a文件夹必须提前存在才可以


!!!!!!!!!!!!!!
uname -a ------------------- 查看服务器环境 
// 比如:Linux VM-0-4-centos 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

whereis name --------------- 找出本系统中的文件路径

!!!!!!!!!!!!!!
whoami --------------------- 查看当前登陆用户名


su + 用户名称 --------------- 切换用户名称
su 是 ( switch user ) 的缩写


scp ------------------------ 安全复制文件和目录
scp [可选参数] source_file target_file
scp -r source_file target_file 
  - -r 表示递归 ( recursive是递归的意思 )
  - scp 是 ( secure copy ) 的缩写,表示安全复制
  - 表示递归的将source_file文件夹复制到target_file文件夹
  
  
ps ------------------------- 用来显示当前进程的状态
ps [options]
ps -e
ps -A 两个都表示查看所有进程
ps -f 全格式显示进程
ps 是 ( process status ) 当前进程状态的意思


tr ------------------------- 转换 或者 删除 文件中的字符
tr 指令从标准输入设备读取数据,经过字符串转译后,将结果输出到标准输出设备
r 是 translate 的简写,表示转换
tr -d ---------------------- 删除
tr -d '\r' ----------------- 删除回车符

(5) yml 语法

1. yml 数据结构
- 一共有三种数据结构
- 对象 数组 纯量


2. 对象
- 键值对的集合,又称 mapping hashes dictionar
- 写法
  key:value
  或者:object: { key: val, key: val }


3. 数组
- 一组按次序排列的值,又称 sequence list
- 写法
  - one
  - two
  - three
  或者:animal: [one, two]

3. 纯量 scalar
- 单个的,不可再分割的值
- number string boolean null date time
- null 用 ~ 表示
- 字符串 多行字符串可以使用 |
4. 复合结构的写法
---

sex:
 - male
 - female
website:
  baidu: baidu.com
  google: google.com
  
转成js是

{
  sex: ['male', 'female']
  website: {
    baidu: 'baidu.com',
    google: 'google.com'
  }
}


5. 引用 & * <<
---

& 锚点
* 别名
<< 合并到当前数据
---

例1
obj: &obj
  key1: val1
  key2: val2
score:
  en: 10
  <<: *obj
相当于
obj:
  key1: val1
  key2: val2
score:
  en: 10
  key1: val1
  key2: val2
---

例2
- &var one
- two
- *var
相当于
- one
- two
- one


6. yml注意事项
- 大小写敏感
- 锁进不能使用tab,只能使用空格
- 缩紧的空格数可以任意,但必须对齐,表示层级

(一) SSH 免密登录远程服务器

(一) ssh相关概念
- ssh
  - ssh就是一种协议,用来登录远程服务器
  - ssh是 ( secure shell ) 的缩写
- openSSH
  - 是ssh协议的免费开源实现
  - 分类
    - 客户端:openssh-client
    - 服务端:openssh-server
    - 一般linux,mac上都内置了openssh-client
  - 访问
    - 访问远程服务器:--- 本地只需安装openssh-client,而远程服务器需要安装openssh-server
    - 本机被访问:------ 本地也需要安装openssh-server


(二) 安装
- sudo apt-get/或yum/或brew  install openssh-client 
- sudo apt-get/或yum/或brew  install openssh-server 


(三) 相关命令
以下都是针对server端
查看ssh服务是否开启 ----------- netstat -tlp | grep ssh
启动ssh服务 ------------------ sudo /etc/init.d/ssh start
停止ssh服务 ------------------ sudo /etc/init.d/ssh stop
重启ssh服务 ------------------ sudo /etc/init.d/ssh restart 或者 service sshd restart
---
( 重启 ) 这里有个坑,注意
- 在腾讯云centos中通过 service sshd restart 重启
  - 报错:Redirecting to /bin/systemctl restart sshd.service
  - 解决:systemctl restart sshd.service
- 现在都换成了以下命令
  - 查看:systemctl status sshd.service
  - 启动:systemctl start sshd.service
  - 重启:systemctl restart sshd.service
  - 自启:systemctl enable sshd.service
  - systemctl 是 stytem control 的意思


(四) 登录
ssh一共有两种登录方式 ( 口令登录 ) ( 公钥登录 )
- 口令登录 
  - 即输入用户名,密码 
  - ssh -p 端口号 -i 认证证书 用户名@服务器ip
  - 登录后服务器的公钥会被保存到本地的 ( $HOME/.ssh/known_hosts ) 文件夹中
- 公钥登录 
  - 即免密登录,不需要密码就能登录


(五) 口令登录
- 口令登录,第一次登录时会出现一个提示
   > The authenticity of host 'host (12.18.429.21)' can't be established.
   > RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
   > Are you sure you want to continue connecting (yes/no)?
- 这里表示是否接受 ( 远程服务器的公钥 ),接受公钥后,会弹出一个警告,接着会让输入密码即可登录
- ( 服务器的公钥 ) 保存在本机的位置:( $HOME/.ssh/known_hosts ),下次登录就不会有警告,而是直接提示输入密码
  - 对比
  - 服务端:( 用户公钥 )保存在( 远程服务器 )的位置:( $HOME/.ssh/authorized_keys )
  - 客户端:( 远程服务器公钥 )保存在( 本地 )的文职:( $HOME/.ssh/know_hosts )
  
  
(六) 公钥登录
- 公钥登录的好处
  - 不用每次登录都输入 ( 密码 )
  - 但是还是要输入 ssh -p 端口 -i 认证证书 用户名@服务器ip
- 要求
  - 公钥登录需要提供本机的公钥,所以没有的话就需要用 ( ssh-keygen ) 命令生成公钥,一路回车即可
  - 私钥:.ssh/id_rsa
  - 公钥:.ssh/id_rsa_pub
- 具体步骤
  - 1. 本机没有公钥用 $ ssh-keygen 生成 --- $ ssh-keygen
  - 2. 将本机的公钥传送到远程服务器的上:----- $ ssh-copy-id user@hot
       - (1) ssh-copy-id 会将公钥写到远程主机的 ( ~/.ssh/authorized_key ) 文件中
       - (2) 或者 scp -r id_rsa.pub user@ip /root/.ssh/authorized_keys
  - 3. 之后登录就不需要再输入密码了
- 如果经过了12步还是不成功,可能是远程服务器的ssh设置没有被打开
  - 1. 需要打开远程主机 /etc/ssh/sshd_config 这个文件,把下面几行的#号去掉,#表示注释
    - RSAAuthentication yes\
   - PubkeyAuthentication yes\
   - AuthorizedKeysFile .ssh/authorized_keys
    - PermitEmptyPasswords 设置成yes
  - 2. 重启远程ssh服务
    - ubuntu系统:service sshd restart
    - debian系统:/etc/init.d restart
    
 
(七) authorized_keys 文件
- 服务端authorized:( 用户公钥 )保存在( 远程服务器 )的位置:( $HOME/.ssh/authorized_keys )
- 客户端:( 远程服务器公钥 )保存在( 本地 )的文职:( $HOME/.ssh/know_hosts )
- 公钥是一段字符串,只需要把它追加到 authorized_keys 文件的末尾就行


(八) 遇到问题:
 - 1. 每次ssh登录都要输入密码,我们使用了 -------------------- 公钥登录
 - 2. 但是公钥登录还是要输入user@ip等信息,麻烦,怎么解决? ----- 服务器别名登录 config


(九) 服务器别名 - config
- 在客户端 $HOME/.ssh/cofig 中做服务器别名的配置
- ssh登录时就可以直接输入 ( ssh -i id_rsa Host别名 ) 即可登录

Host example                       # 关键词
    HostName example.com           # 主机地址
    User root                      # 用户名
    # IdentityFile ~/.ssh/id_rsa # 认证文件,如果不想每次都输入 ssh -i id_rsa,可以打开该配置,打开后,就可以通过 ssh 别名
    # Port 22                      # 指定端口,ssh默认端口是22,是默认端口可以不设置
    
Host ------------------- 昵称,用来标识某个特定的配置,用于在ssh命令中使用,比如 ssh example 来直接连接主机,省略写用户名@ip
HostName --------------- 需要连接的主机名
User ------------------- 登录主机的用户名
IdentityFile ----------- 认证证书文件,默认位置 ~/.ssh/id_rsa
Port ------------------- 被访问主机的端口号


(十) 总结
- 客户端config + 服务器authorized_keys = 别名免密登录

image.png

image.png

(二) Docker

(1) Dockerfile

语法说明
FROM引用基础镜像 - FROM...as
as的作用(如下)
- 1. 在输入 docker build --target <as的值> 命名时,指定构建具体的镜像,因为dockerfile中可能有多个FROM指定基准镜像
- 2. 在多阶段构建中,COPY --from=<as名称> 获取中间层镜像中的数据
WORKDIR当前的工作目录,即是进入容器后,默认所在的当前目录
注意:不是本机目录,是容器中的目录
注意:在多阶段构建时,WORKDIR在各层都起作用
WORKDIR指令为Dockerfile中的任何RUN,CMD,ENTRYPOINT,COPY和ADD指令设置工作目录
如果WORKDIR不存在,它将被创建,即使它没有在任何后续的Dockerfile指令中使用
RUN在新建镜像时执行的命令 ---------------------- 构建镜像阶段
比如 RUN yum -y install Vim 表示用yum来安装 Vim 包
CMD设置容器启动后默认执行的命令和参数 -------- 容器运行阶段
比如 CMD /bin/bash
- 如果docker run的时候指定了其他CMD命令,Dockerfile中的CMD命令被忽略;
- 如果定义了多个CMD,只有最后一个会执行
- CMD ["/bin/echo","hello docker"]
- 注意:CMD数组成员只能是双引号,单引号会出错
- 注意:CMD 能够被 docker run 后面跟的命令行参数替换
ENTRYPOINT设置容器启动时运行的命令
EXPOSE暴露端口 - 类似于 docker run -p
--------------------------------
COPY拷贝文件,注意推荐使用copy,因为add不能拷贝 tar 文件
- COPY 源路径 目标路径
- COPY 的路径只能是Dockerfile所在的文件夹,不支持其他的文件夹
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
COPY --from=<as名称> 用来拷贝中间镜像层的数据,主要用于多阶段构建
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ADDADD除了COPY还有额外解压功能,还能指定一个url
- ADD 源路径 目标路径
--------------------------------
ENV设置容器内的环境变量和常量
在其他地方通过 ( $ ) 来引用该环境变量的值
注意:ENV需要在不同的中间层镜像中重新指定,也就是说只能用于一个构建阶段
ARG定义创建镜像过程中使用的变量,编译成功后不存在
在运行docker build时,指定 --build-arg 为变量赋值
- 比如:docker build --build-arg=<参数名>=<值>
- 技巧:可以把ARG声明的变量赋值给ENV,在输入命令时指定ARG,传递
ARG 指令有生效范围,如果在 FROM 指令之前指定,那么只能用于 FROM 指令中
ARG 是 arguments 的缩写
--------------------------------
MAINTAINER维护者 - maintainer
name<邮箱或者电话>
LABEL对镜像的描述,类似于注释,没有什么实际功能 - label
name="xxxx" \
date="xxxx"

(2) 通过Dockerfile生成容器

docker build -f Dockerfile文件的路径 -t 镜像名:标签名 .
docker build --target node --build-arg NAME=woow -f Dockerfile -t tomcat .

// -f 是file的缩写
// -t 是tag的缩写
// --build-arg <变量名=变量值>,用来覆盖ARG指定的变量
// --target <as的值>,用来明确的指定需要构建的target。Dockerfile 中有 FROM node as node 的写法

// 注意:最后面的 . 表示当前路径,不要忘记了
// 详细:这个.是一个有空格的 ` .` 这个 ( . ) 的意思是指定 ( 镜像构建过程中的上下文环境的目录 )
// 注意:如果不通过 -f 指定Dockerfile的话,Dockerfile首字母一定要大写

(3) 编写一个完整的前端部署的Dockerfile文件

(1) Dockerfile多阶段构建
---

####### node

From node as build 

ENV WORK_DIR /app

WORKDIR ${WORK_DIR}

COPY . ${WORK_DIR}

RUN npm install -g cnpm --registry=https://registry.npmmirror.com

RUN cnpm install

RUN cnpm run build


####### nginx

From nginx as nginx

ENV WORK_DIR /app 

COPY --from=build ${WORK_DIR}/build /usr/share/nginx/html

COPY --from=build ${WORK_DIR}/docker/nginx/conf.d /etc/nginx/conf.d

# COPY --from=build ${WORK_DIR}/nginx.conf /etc/nginx/nginx.conf 这个是nginx的配置,而不是容器中nginx的配置

# COPY /docker/nginx/conf.d /root/etc/nginx/conf.d

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"] 
# 这里之所以要执行nginx -g daemon off; 是为了让容器退出后不关闭
(2) 通过Dockerfile构建镜像
---

docker build -t ngin_deploy .
(3) 通过镜像生成容器
---

docker run -d -p 8020:80 ngin_deploy
(4) 测试
---

http://120.53.220.141:8020/

image.png

image.png

(三) docker-compose

(1) 安装

1 安装 - linux版本安装
---

1. 运行此命令以下载 Docker Compose 的当前 stable release 稳定版本
- sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- 如果上面的链接太慢,可以使用下面的命令
- curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

2. 将可执行权限应用于二进制文件
- sudo chmod +x /usr/local/bin/docker-compose

3. 测试是否安装成功
- docker-compose --version

(2) docker-compose.yml

  • 一些概念
    • 服务service:表示一个应用容器
    • 项目project:由一组关联的 ( 应用容器 ),( 组成的 ) 完整 ( 应用单元 )
  • Dockerfile 缺点
    • 在Dockerfile中,其实volume是很不好用的,在容器中好找,但是主机中是匿名文件夹,所以还得在build构建完镜像后,通过docker run 生成容器时,在通过 -v 来指定数据卷
  • 解决
    • 所以我们直接通过 docker-compose 来解决 volume数据卷映射单服务器的服务编排 语法|说明 |-|-| version|(一级) 指定compose文件的版本args,不可缺少的字段 services|(一级) 指定所有的 service,注意是复数 ----------------|---------------- image|指定镜像 container_name|指定容器名 working_dir|指定容器的工作路径,相当于Dockerfile中的WORKDIR,例如:/
      注意:这里只能是绝对路径 environment|设置环境变量,类似于Dockerfile中的 env
      例如:- MYSQL_ROOT_PASSWORD=root volumes|数据映射
      缩写:-"../nginx/config/conf.d:/etc/nginx/conf.d"
      注意:这里用相对路径指定宿主机路径,即docker-compose.yml所在的文件
      注意:相当于命令 -v
      注意:是复数 volumes
      注意:对应的是一个字符串 ports|端口映射,相当于 docker run -p 宿主端口:容器端口
      target: 容器端口
      published:宿主机端口
      缩写:'3033:30'
      注意ports 是map数据结构,不是数组
      相当于-p 主机端口:容器端口
      注意:这里的写法如果指定 target等时第一个加 - ,具体见下面的实例 ----------------|---------------- depends_on|定义容器启动先后顺序,表示依赖关系
      注意depends_on 是一个组数语法,成员是 service 的值 command|容器启动后默认执行的命令,相当于 docker exec -it 容器 命令 /bin/bash build|build主要用来:构建Dockerfile,指定包含构建上下文的路径,或作为一个对象
      该对象具有 ( context ) , ( Dockerfile ), ( args )
      context:指定Dockerfile文件所在的路径
      dockerfile:指定Dockerfile文件的名称,默认是Dockerfile
      args:Dockerfile在build过程中需要的参数

(3) docker-compose 常用命令

docker-compose -v                                // docker-compose的版本号,常用来查看docker-compose是否安装成功

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

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

docker-compose images                            // 列出项目中所有镜像
docker-compose ps                                // 列出项目中所有容器
docker-compose start 容器名		         // 启动容器
docker-compose restart 容器名                     // 重启容器,其实这些命令大多和docker的命令保持一致
docker-compose stop  容器名                       // 停止容器
docker-compose restart 容器名                     // 重启容器
docker-compose rm 容器名                          // 删除容器( 删除前需要停止容器 docker-compose stop 容器名|ID )
docker-compose logs                              // 查看日志

(4) 通过 docker-compose 来部署完成的前端项目

version: "3"
services:
  deploy:
    restart: always
    container_name: deplay_c1
    working_dir: /
    ports:
      - "8020:80"
    build:
      context: .
      dockerfile: Dockerfile

image.png

(四) gitlab-ci

(1) 一些概念

1. 一些概念
pipeline stages jobs
---

- pipeline 管道
  - pipeline 中包含多个 ( 串行的stage )
  - 一个 stage 失败,则整个pipeline失败
- stages 阶段
  - stage 中包含多个 ( 并行的job )
  - 一个 job 失败,则整个stage失败
- jobs 工作

(2) 安装和注册 gitlab-runner

(一) 要使用gitlab的ci/cd功能,只需要两步
---

1. Ensure you have runners available to run your jobs. If you don’t have a runner, install GitLab Runner and register a runner for your instance, project, or group.
  - 需要 gitlab-runner 
  - gitlab-runner主要用来跑 gitlab-ci.yml 中定义的 jobs
  
2. Create a .gitlab-ci.yml file at the root of your repository. This file is where you define your CI/CD jobs.
  - 在项目的根目录下创建 .gitlab-ci.yml 文件
(二) 安装 gitlab-runner
https://docs.gitlab.com/runner/install/
---

我们使用docker来安装 gitlab-runner,具体步骤如下
---


1. 拉取 gitlab/gitlab-runner 镜像
- docker pull gitlab/gitlab-runner:latest


2. 
To run gitlab-runner inside a Docker container, 
you need to make sure that the configuration is not lost when the container is restarted. 
To do this, there are two options, which are described below.
- 在用容器跑gitlab-runner之前,你需要保证容器中的数据不会丢失(正常情况下,容器stop后数据就会丢失),我们要做两个设置
- 其实就是创建容器的数据卷映射
- -v /srv/gitlab-runner/docker-machine-config:/root/.docker/machine
- -v docker-machine-config:/root/.docker/machine


3.  生成 gitlab-runner 容器并保证是正常运行状态
Use local system volume mounts to start the Runner container
- 我们使用系统数据卷映射,而不是数据卷容器,所以执行一下命令
docker run -d --name gitlab-runner --restart always \ 
-v /srv/gitlab-runner/config:/etc/gitlab-runner \ 
-v /var/run/docker.sock:/var/run/docker.sock \ 
gitlab/gitlab-runner:latest

---

docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
(三) 注册 gitlab-runner
https://docs.gitlab.com/runner/register/
---

1.
Registering a runner is the process that binds the runner with one or more GitLab instances.
You can register multiple runners on the same host machine, 
each with a different configuration, by repeating the `register` command.
- 注册runner是把runner和一个或多个实例绑定的过程,同一台机器可以注册多个runner,不同配置
- 注册gitlab-runner之前当然需要先安装gitlab-runner

2. 
Obtain a token
- 获取 runner 的 token
- 一共有三种runner:specific项目独享,shared可用于多个项目,group用于项目组
- 具体在哪里获取:
  - gitlab项目/setting/cicd/runners下展开可以看到
- 获取哪些内容
  - 获取 URL 和 token
  
3. 
Run the register command based on the mount type:
For local system volume mounts
- 运行注册命令基于mout类型,这里我们使用的是本地数据卷形式
- 安装过程中会有提示,按提示进行安装,注意 URL,token 是上面第2步获取的 URL,token
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register

4. 具体步骤见
- [React 从零实践05-后台] Gitlab-CI使用Docker自动化部署
1. 生成注册用的docker容器
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
2. 运行上面步骤1的命令后,进入交互式注册命令过程,过程进入第3步
3. Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
   https://gitlab.com/
4. Please enter the gitlab-ci token for this runner
   jKKqXFTaMyBNNPwy-vFJ
   // 如何获取token => gitlab网站对应的项目/setting/CICD/Runners/Specific Runners中获取token
5. Please enter the gitlab-ci description for this runner
   7-react-admin-ts-runner
6. Please enter the gitlab-ci tags for this runner (comma separated)
   7-react-admin-ts-runner // tag
7. Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell
   docker // 1. 输入执行器,多数情况下都使用docker
   shell  // 2. 如何在deploy阶段,因为需要拷贝dist文件夹,则deploy的job可以使用shell来获取通过dependencies获取的artifacts
8. Please enter the Docker image (eg. ruby:2.6)
   node // 镜像,主要作用是如果在 ( .gitlab-ci.yml ) 文件中没有指定image,就会使用这里指定的image
输入完以上命令,会提示注册成功,同时在 => gitlab网站对应的项目/setting/CICD/Runners/Specific Runners中获取token中会显示刚刚注册的runner

(3) ssh-key

  • 主要用于免密的项目克隆,打包,和文件拷贝等
  • ssh官网说明
如何创建ssh-key
---

1. 什么时候需要ssh
- 用包管理工具下载私有包
- 将应用程序部署到自己的服务器上
- 从构建环境ssh登录到服务器环境
- 将文件从构建环境同步到服务器环境


2. Create a new SSH key pair locally with ssh-keygen
- 在本地环境创建ssh,这里的本地环境指的是 .gitlab-ci.yml 所在的服务器环境


3. Create a new CI/CD variable. 
As Key enter the name SSH_PRIVATE_KEY and in the Value field paste the content of your private key that you created earlier.
- 创建一个 ci/cd变量
- key: SSH_PRIVATE_KEY
- value: id_rsa


4. Modify your .gitlab-ci.yml with a before_script action. 
In the following example, a Debian based image is assumed. Edit to your needs:
- 修改 .gitlab-ci.yml 中的 before_script 部分,如下
---
before_script:
  - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  - mkdir -p ~/.ssh 
  - chmod 700 ~/.ssh


5. Make sure the private server’s SSH host keys are verified.
- 确保 ssh host keys 是通过验证的
- 具体步骤如下
  - 输入命令 ssh-keyscan www.gitlab.com
  - 添加cicd变量 
    - key: SSH_KNOWN_HOSTS
    - value: ssh-keyscen 输出的内容

6. 在 before_script 上追加上一下内容
before_script:
  - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  - mkdir -p ~/.ssh 
  - chmod 700 ~/.ssh
  - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts 
  - chmod 644 ~/.ssh/known_hosts

image.png

image.png

image.png

image.png

资料

ssh blog.csdn.net/li528405176…
ssh2 www.cnblogs.com/toughlife/p…
centos yum安装报错 segmentfault.com/a/119000004…
Dockerfile案例 www.qiyuandi.com/zhanzhang/z…
yml语法 www.ruanyifeng.com/blog/2016/0…