提示:本系列笔记全部存在于
Github
可以直接在
Github 查看全部笔记

这一篇主要讲述部署一个 Web 项目,项目是我曾经搞的一个 VUE 模板项目:https://github.com/orca-studio/vue-template/tree/vite-3.X

目前还没有搭建镜像私有仓库和自动化部署流程。

只能本地打包 Docker 镜像,上传 DockerHub,再服务器拉取镜像,进行启动。

本地打包 Docker 需要本地具有 Docker 环境。

WindowsMacDocker 环境,可以在网上查询怎么安装。

构建镜像

部署 Web 项目 的第一步是构建 镜像(Image)

镜像(Image) 是运行时所使用的文件资源。

Docker 提供了制作 镜像(Image) 的方式:使用 build 命令执行 Dockerfile 文件。

构建 镜像(Image) 的关键 就在于 Dockerfile 文件。 Dockerfile 配置了构建镜像时所有的操作。

执行 build 时,需要提供一个 上下文目录(Context)(一般上下文目录为项目根目录)。

Docker 会将上下文目录(Context) 与子目录结构发送到 Docker 引擎Docker 引擎 根据这个目录结构去构建 镜像 (Image)

Dockerfile 文件中,是不允许访问 上下文目录(Context) 之外的目录。

这就是有些教程中会说不能在 Dockerfile 使用 ../ 原因。

默认情况下 Docker 会读取 上下文目录(Context)Dockerfile 文件,所以一般都会将 Dockerfile 文件放在根目录。

当然也可以放在其它目录,执行 build 时使用参数指定 Dockerfile 文件

PS: 注意:在构建 镜像 时不允许访问 上下文目录(Context) 之外的目录。

Dockerfile

为了管理方便,将所有的部署相关放在 deploy 目录。

所以也将 Dockerfile 存放在 deploy 目录。

FROM nginx:latest

# 将代码copy到镜像
COPY ../dist /usr/share/nginx/html # 将 nginx 配置文件 copy 到容器内配置文件的目录下
COPY ../deploy/nginx.conf /etc/nginx # 容器应用端口
EXPOSE 80

PS:Dockerfile 支持好多指令,在此只介绍使用到的指令,其它指令有兴趣的朋友可以自行查询

  • 第一行 FROM 指令:表示使用的底层镜像,制作应用级别镜像,都需要依赖运行环境。web 项目的运行环境为 Nginx 服务器。

    PS: 之前说过, 镜像是分层存储的,构建镜像可以简单的理解为在现有镜像上添加一层。

  • 第二行 COPY 指令:表示 复制文件,将本地的目录或者文件 复制到镜像指定目录下。

    ./dist 目录,也就是项目编译生成的代码目录复制到 镜像中 /usr/share/nginx/html 目录

    PS:所有相对目录都是以 上下文目录(Context) 为基准,所以 dist 目录访问是 ./dist,而非 ../dist

  • 第三行 COPY 指令:表示将 nginx.conf 配置文件 复制到 /etc/nginx

    PS:所有相对目录都是以 上下文目录(Context) 为基准,所以 nginx.conf 目录访问是 ./deploy/nginx.conf,而非 ./nginx.conf

    web 项目 容器 运行的是 Nginx 服务器, 自己制作的 web 镜像 镜像(Image) 只是将生成的静态文件挂载到 Nginx 服务器上。

    nginx.conf 文件是用来配置 Nginx 挂载路由等信息。

  • 第四行 EXPOSE 指令:暴露端口号,启动容器时使用 ports 映射容器内部的端口号就是此命令暴露的。

Nginx 镜像中,暴露了 80 端口运行 Nginx 服务器,Dockerfile 中只暴露 80 端口,在启动时 80 端口直接启动的是 Nginx 服务器。

注意:不允许直接使用 ./nginx.conf 访问,会被识别成以 上下文目录(Context) 下的 nginx.conf

但是允许以 上下文(目录)为相对目录的基准目录。

nginx.conf

deploy/nginx.conf 文件中编写 Nginx 配置。 构建镜像(Image)时会将此文件复制到镜像

PS: 也可以使用类似上一篇中的将 nginx.conf 挂载到宿主环境中。

events {
worker_connections 1024;
} http {
include mime.types;
default_type text/html;
sendfile on;
keepalive_timeout 65;
charset utf-8;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
server {
listen 80; location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
  • root: 此属性设置根目录,当前根目录设置为 /usr/share/nginx/html,静态文件都存储在此目录。
  • index: 此属性指定网站初始页面。 也就是 /usr/share/nginx/html/index.html
  • try_files: 此属性将所有的访问都转为 index.html 。单页面程序的路由都是请求同一个 HTML,由 JS 内部判断的路由页面,

    类似 webpack-dev-serverhistoryApiFallback 属性

执行构建

执行构建 镜像(Image) 使用的命令是 docker build

为了执行方便,在 package.json 中添加 deploy 命令执行构建

每次构建 镜像(Image) 前,先进行项目编译。也就是执行 npm run build 命令。当编译成功后才执行 docker build

PS: npm-run-all 是一个 NPM 包,用于执行多个脚本

PS: Docker Hub 没有账号的需要先进行注册:https://hub.docker.com/

docker build 命令中使用了几个参数

  • -t 构建的镜像名称。 其中 yxs970707Docker Hub 中的用户名称。

    当前没有构建私库,先推送到 Docker Hub。将 yxs970707 改为自己用户名称或组织。

    : 后的为当前镜像的 标签(tag),一般情况下会设置版本号。

    也可以使用多个 -t 设置多个版本号
  • -f Dockerfile 文件地址,Dockerfile 文件存在了 deploy 目录,所以需要指定文件地址。
  • 最后一个点 . 表示设置当前目录为 上下文目录(Context)

PS:标签(tag) 可以随意设置,标签(tag) 可以根据实际情况使用版本号

PS: 构建镜像时可以设置多 标签(tag),添加多个 -t

此时,执行 npm run deploy 便可以构建镜像(Image)。构建镜像(Image)时,每一句命令都具有清晰的信息。构建成功后就可以在本地 Docker 中看到此镜像

PS:第一次构建可能会慢一些,因为本地没有 Nginx 镜像,需要 pull。

PS:镜像(Image) 的分层其实每一句命令都是一层。


测试镜像

成功构建镜像后可以先在本地测试

在此将本地 3333 端口号映射到了容器。可以根据情况随意设置未被使用的端口号,

如果未出意外的话将会启动一个 容器,容器状态为 RUNNING


如果启动时出错的话,可以点击容器查看错误日志进行分析

按照步骤理论上不会有什么问题,如有未成功的可以查询日志尝试解决,实在解决不了可以留言。

推送 Docker Hub

镜像推送 Docker Hub 很简单,只需要在 Docker Desktop 中登录账号点击 push 即可

PS:之后部署私有仓库之后可以推送到私有仓库

push 成功后就可以在 Docker Hub 中搜到此镜像



部署容器

最简部署

容器的最简部署方案是只设置端口号

拉取镜像可能有些延迟,因为 Docker 配置了国内源,需要时间来同步

version: '3.9'
services:
nginx:
image: yxs970707/deploy-web-demo:1.0.0
container_name: web
restart: always
ports:
- 7777:80

PS:镜像(Image)标签(tag) 设置的为 1.0.0,拉取镜像时需要指定

使用 Portainer 部署完毕后就可以访问服务器进行访问。


volumes 挂载

在上面将所有文件都存放镜像中,并没有使用 volumes/usr/share/nginx/html 目录挂载到宿主机中。

接下来就实现这一操作,将数据挂载到宿主机中。

将数据挂载到宿主机中可以实现不更新镜像和容器直接更新前端项目。

但是真实情况下并不推荐这样做。这里只是介绍下可以这样做,在后续自动化部署时还是根据镜像版本更新。

非具名 volumes 覆盖问题

之前都是使用宿主目录直接挂载容器内目录。

直接使用宿主目录挂载,在容器启动时会使用宿主目录覆盖容器目录。

version: '3.9'

services:
nginx:
image: yxs970707/deploy-web-demo:1.0.0
container_name: web
restart: always
ports:
- 7777:80
volumes:
- /volumes/web/html:/usr/share/nginx/html

更新 YMAL 文件,添加挂载 /usr/share/nginx/html 目录。

使用此文件重新部署,访问时 Nginx 会提示 403,也就是根本没有找到该地址

/usr/share/nginx/html 目录是存储前端文件的目录。

在服务器查看会发现挂载目录并没有任何文件,进入容器内部查询 /usr/share/nginx/html 也没有任何文件

也就是说 Docker 在启动容器时,使用宿主目录(空目录)覆盖了容器内目录。


docker exec -it web /bin/sh 进入容器

可以在宿主目录创建一个文件测试,在此只贴出测试结果。有兴趣的可以自行测试。

具名 Volumes

解决数据挂载问题,需要创建具名的 Volumes。

DockerVolume 是一个完整的模块。具有很强大的功能。

甚至可以将数据挂载到其它机器上,在此只使用 Volume 完成目前的需求。

其它功能,有兴趣的朋友可以自行查询稳定。

Volume 可以使用命令先进行创建,然后在挂载时使用。当然可以在 Docker Compose 创建。

version: '3.9'

volumes:
web-html:
name: web-html
driver: local
driver_opts:
o: bind
type: none
device: /volumes/web/html services:
nginx:
image: yxs970707/deploy-web-demo:1.0.0
container_name: web
restart: always
ports:
- 7777:80
volumes:
- web-html:/usr/share/nginx/html

YAML 文件中 volumes 就是创建具名的数据卷。

这个数据卷使用了本地数据卷,将数据卷绑定本地 /volumes/web/html 目录

PS: 数据卷还具有其它绑定方式,比如使用 IP 绑定其它机器。

然后使用 数据卷名称(web-html) 挂载容器 /usr/share/nginx/html

注意,使用数据卷名称挂载时, /volumes/web/html 目录必须存在,目录下不允许有文件。

使用此 yml 部署便可以将数据挂载到 /volumes/web/html


仔细观察的情况下, Portainer 可视化工具中在 Volume 项此时具有一个 web-html 的数据卷

在其详细信息中可以看到具体详情。

其中具有一个 Mount path 属性,这个属性值是此数据卷的目录。

其实在 Docker 挂载数据卷时,会将此目录与容器内进行挂载。

另外还有一个 device 属性,这个数据是与数据卷绑定的目录。Linux 具有一种可以将 Mount pathdevice 绑定为一个目录方案

当然还可以使用其它绑定方案,将数据卷绑定到其它目录。甚至可以绑定到其它机器

私有化轻量级持续集成部署方案--03-部署web服务(上)的更多相关文章

  1. 私有化轻量级持续集成部署方案--04-私有代码仓库服务-Gitea

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 企业级最流行的私有代码仓库是 Gitlab, 一开始我也打算部署 Gitlab作为私有代码仓库. 但部署完 d 成后 ...

  2. 私有化轻量级持续集成部署方案--06-私有镜像仓库-Harbor

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 针对私有镜像仓库的问题,Docker 官方提供了搭建仓库服务的镜像服务:registry,使用此镜像就可以部署私有仓 ...

  3. 私有化轻量级持续集成部署方案--05-持续部署服务-Drone(上)

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 持续部署概述 持续部署是能以自动化方式,频繁而且持续性的,将软件部署到生产环境.使软件产品能够快速迭代. 在之前部署 ...

  4. 私有化轻量级持续集成部署方案--07-私有NPM仓库-Verdaccio

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 对于个人来说,私有NPM仓库 作用性基本很小,但是对于企业,私有NPM仓库 可以保护代码暴露,具有很大的意义. 也是 ...

  5. 私有化轻量级持续集成部署方案--02-Nginx网关服务

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 这一篇中使用 Nginx 部署网关中心,用来代理服务器中服务.网关中心有优点也有缺点,也可以不采用网关系统. 部署 ...

  6. 私有化轻量级持续集成部署方案--03-部署web服务(下)

    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 配置接口代理 前后端分离情况下,前端请求后端接口最常用的一种方式就是使用反向代理,反向代理会让浏览器认为是同源路径, ...

  7. 持续集成环境--Tomcat热部署导致线程泄漏

    一.问题由来 我们组用jenkins部署了持续集成环境,(jenkins部署war包到远程服务器的tomcat). 每次提交了代码,jenkins上一键构建,就可以自动拉取最新代码,打war包,热部署 ...

  8. 用Jenkins+Gradle+Jetty实现持续集成、测试、部署

    自动集成有很多种方案,本例用到的工具是Jenkins(前身Hudson)+Gradle+Jetty,关于Gradle可参考上一篇,Gradle常见问题. 本例项目名称: WAP Jetty 安装Jen ...

  9. 持续集成之Jenkins自动部署war包到远程服务器

    一.无war包链接的情况 无war包链接时,需先下载war包到本地,然后执行: ---------------------------------------------以下部分为转载-------- ...

随机推荐

  1. SCryptPasswordEncoder 单向加密 --- 心得

    1.前言 * BCryptPasswordEncoder相关知识:* 用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的s ...

  2. Thrift框架-具体使用

    1.前言 使用thrift心得: (1)thrift是一个RPC的框架  ,RPC是远程过程调用协议:用于进行可扩展且跨语言的服务的开发,以构建在C++.Java.Python.PHP.Ruby.Er ...

  3. 第10组 Beta冲刺 (5/5)

    1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/p/14018671.html ·作业博客:https://edu.cnblogs.co ...

  4. java集合对比汇总

    List.Set和Map: List是有序的集合,Set是无序的集合.Map是无序的键值对. HashMap详解: HashMap有两个参数影响其性能:初始容量和加载因子.默认初始容量是16,加载因子 ...

  5. 一条 Git 命令减少了一般存储空间,我的服务器在偷着笑

    元旦不是搭建了一个<Java 程序员进阶之路>的网站嘛,其中用到了 Git 来作为云服务器和 GitHub 远程仓库之间的同步工具. 作为开发者,相信大家都知道 Git 的重要性.Git ...

  6. day3 创建数组并完成对数组的操作

    1.实现函数action()初始化数据全0的操作 2.实现函数assignment()利用指针给数组赋值0~9 3.实现函数print()打印数组的每个函数 4.实现函数reverse()完成对数组的 ...

  7. HBase之MinorCompact全程解析

    转自:https://blog.csdn.net/u014297175/article/details/50456147 Compact作用 当MemStore超过阀值的时候,就要flush到HDFS ...

  8. 根据SVG Arc求出其开始角、摆动角和椭圆圆心

    SVG Arc 目前Svg的Arc的参数字符串如下: a rx ry x-axis-rotation large-arc-flag sweep-flag x y 除了a表示标识为Arc之外,其余参数说 ...

  9. golang中自定义一些类型和对应类型的指针方法

    package main import "fmt" // 项目开发中可以为type声明的类型编写一些方法,从而实现对象.方法的操作 // 声明类型 type myInt int / ...

  10. 手把手教你丨小熊派移植华为 LiteOS-M

    摘要:本文详细讲解如何移植 LiteOS 到小熊派. 本文分享自华为云社区<小熊派移植华为 LiteOS-M(基于MDK)>,作者: JeckXu666. 前言 之前使用小熊派实现了鸿蒙动 ...