提示:本系列笔记全部存在于
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. JS 在使用hasOwnProperty()函数时报错

    在使用hasOwnProperty()方法判断对象是否具有某种属性时eslint报下列错误: Do not access Object.prototype method 'hasOwnProperty ...

  2. Linux上天之路(五)之Linux基本命令

    1. Linux命令格式 命令 命令选项 学会看语法: {必选项}[可选项] 举例 ls -a /tmp 等价 ls –all /tmp ls 命令 -a 命令选项 简写使用- 全写-- /tmp 参 ...

  3. LINUX学习-Mysql集群-主主备份

    接着主从备份继续. 1.编辑主从服务器 vim /etc/my.cnf 在server-id下添加一句 忽略一些信息 binlog-ignore-db=mysql 2.从服务器也授权给主服务器 gra ...

  4. 深入理解MySQL索引底层数据结构

    作者:IT王小二 博客:https://itwxe.com MySQL 索引相关的数据结构有两种,一种是 B+tree,一种是 Hash,那么为什么在 99.99% 的情况下都使用的是 B+tree索 ...

  5. 【golang学习记录】环境搭建

    [golang学习记录]环境搭建 一. 概述 本文是[golang学习记录]系列文章的第一篇,安装Go语言及搭建Go语言开发环境,接下来将详细记录自己学习 go 语言的过程,一方面是为了巩固自己学到的 ...

  6. 干掉 Postman?测试接口直接生成API文档,ApiPost真香!

    实不相瞒我的收藏夹里躺着很多优质的开发工具,我有个爱好平时遇到感兴趣的开发工具都会记录下来,然后有时间在慢慢研究.前几天刚给同事分享一款非常好用的API文档工具,真的被惊艳到了,粉丝朋友们也感受一下吧 ...

  7. 《剑指offer》面试题28. 对称的二叉树

    问题描述 请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和它的镜像一样,那么它是对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的.     1    / \   2   ...

  8. 记一次oom问题排查

    大家好,我是大彬~ 今天给大家分享最近出现的OOM问题. 上周五早上,测试同学反馈测试环境的子系统服务一直超时,请求没有响应. 收到这个问题之后,我有点纳闷,最近这个系统也没有改动代码逻辑,怎么会突然 ...

  9. Web安全攻防(一)XSS注入和CSRF

    跨站脚本攻击(XSS) XSS(Cross Site Scripting),为不和层叠样式表CSS混淆,故将跨站脚本攻击缩写为XSS. 攻击原理: 恶意攻击者往Web页面里插入恶意Script代码,当 ...

  10. 【刷题-LeetCode】210. Course Schedule II

    Course Schedule II There are a total of n courses you have to take, labeled from 0 to n-1. Some cour ...