企业部署,springboot+vue+vue,Linux上部署mysql与redis,docker中部署nginx,jenkins。完整详细。

news2024/11/25 4:44:10

企业项目部署全流程笔记

前言

涉及:Linux服务器,docker,Jenkins,nginx,springoot,vue,mysql,redis,git,

docker生成容器类型:MySqlRedis,Jenkins,Nginx,项目存放的容器。

注:!!!!!!!!!!!数据库不要存放在Docker中,而且存放会在使用时会有问题。!!!!!!!!!!

  • 存放 mysql 时、发现其账号密码只能是 root 和 123456 其余的密码会出现问题,显示登陆出错。

项目共用MySql,Redis。使用 Jenkins 进行自动化部署项目。前端项目全部存放到 Nginx 中,设置动静分离,子域名映射。容器间使用自定义网络进行通信。

1.登陆Linux服务器

笔者使用腾讯云2核4G,同时使用 Xshell 软件操作服务器。

登陆步骤准备:服务器公网Ip地址服务器密码(若未修改密码可在腾讯云邮箱中找寻初始密码)、服务器账号(默认为 root)

1.1、点击

在这里插入图片描述

1.2、填写公网IP

在这里插入图片描述

1.3、填写用户名

在这里插入图片描述

1.4、填写密码

在这里插入图片描述

1.5、成功

在这里插入图片描述

2、安装 Docker

要求

1、Docker 要求 CentOS 系统的内核版本高于等于3.10

2、若之前安装过,需先删除:

 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

1、安装基本环境

地址

sudo yum install -y yum-utils

在这里插入图片描述

2、设置镜像仓库(若阿里云镜像安装失败则使用官方)
阿里云镜像:
 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
官方镜像:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo


3、安装前先更新 yum 包索引
yum makecache fast

4、安装最新版Docker docker-ce:社区版
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

5、启动
sudo systemctl start docker
(systemctl start docker.service  #后台启动,systemctl enable docker   #设置开机自动启动)

6、运行镜像判断是否安装成功
sudo docker run hello-world

注:可使用 docker version 查看版本信息

在这里插入图片描述

8、查看镜像
docker images

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    9c7a54a9a43c   4 months ago   13.3kB
注:这个hello-world是我刚才编写的,并非自带的

docker rm -f <containerid> 删除指定容器
docker ps # 查询容器
docker stop 容器名 # 停止容器
docker rmi 镜像名 # 删除镜像
docker ps -a # 查询所有容器状态
docker logs f28efc96ac5e # 日志
docker start -a ID # 启动容器容器ID/容器名称 -a参数是显示标准输出,“相当于”前台启动,不带-a参数相当于后台启动。
docker inspect 容器id # 查看容器详细信息

docker rm -f $(docker ps -aq)
# docker ps -aq:列出所有容器的 ID,包括正在运行和已停止的。
# docker rm -f:删除所有列出的容器。 -f 选项表示强制删除,即使容器正在运行也会被停止和删除。
# 请注意,这个命令会永久删除所有容器,包括你可能想要保留的容器。确保在运行之前,你已经备份了需要保留的容器中的数据或设置。

docker search image_name# 查询网络镜像
docker images# 查询本地镜像
docker exec -it 243c32535da7 /bin/bash # 进入容器

3、Docker 自定义网络

因 docker 容器间无法通信,所以在创建容器时设置网络,方便项目容器容器间访问,如果有这方面需要

3.1、生成自定义网络并测试

注:如下内容只作为讲解,观看原理,使用方式即可。后续会有详细步骤。

命令:docker network ls
发现有如下网络:
bridge :桥接 docker(默认)
none:不配置网络
host:和宿主机共享网络
(了解)container:容器网络联通(局限大,不建议)
# 我们直接启动命令默认末尾会带: --net bridge,即docker0,但是我们不使用这个,因为要使用到link关键字,这个关键字现在已经不使用了(弊端:无法通过域名进行访问)
docker run -d -P --name 容器名 --net bridge 

1、创建自定义网络
命令:
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 解释
# docker network create:创建 Docker 网络的命令。
# --driver bridge:指定网络驱动程序。在这里,使用的是默认的桥接(bridge)网络驱动程序,这是 Docker 默认的网络驱动程序,用于在容器之间创建私有网络。
# --subnet 192.168.0.0/16:指定网络的子网。在这个例子中,你指定了一个 IP 地址范围为 192.168.0.0 到 192.168.255.255 的子网。
# --gateway 192.168.0.1:指定网络的默认网关。在这里,你设置了默认网关为 192.168.0.1。
# mynet:这是你为网络指定的名称,你可以根据需要自定义网络名称。

2、查看网络是否创建成功命令
docker network inspect mynet
# config关键字下显示Subnet为 1921.68.0.0/16 Gateway下显示 192.168.0.1

3、创建并运行多个容器(用作测试容器间是否能够访问)
docker run -d -P --name 容器名1 --net mynet  
docker run -d -P --name 容器名2 --net mynet 
# -d:表示容器会以后台(detached)模式运行,也就是在后台运行容器,不会阻塞终端。
# -P:表示 Docker 会自动分配端口,将容器内部的端口映射到宿主机的随机端口上,使得容器的端口可以从外部访问。
# --name 容器名:为容器指定一个自定义的名称,你可以将 "容器名" 替换为你希望的名称。
# --net mynet:指定容器连接到名为 "mynet" 的 Docker 网络。这是一个自定义网络名称,你可以将其替换为你创建的网络的名称。

4、再次查看网络,观察容器是否被分配网络
docker network inspect mynet

5、使用IP进行容器访问,查看是否能够 Ping 通
docker exec -it 容器1 ping 192.168.0.3(这里的IP应该是容器2的IP地址)

6、使用名字进行 Ping 测试
docker exec -it 容器1 ping 容器2

# 注:上述两种方式均应成功

3.2、跨网络联通

上述创建了 192.168.0.0/16 的网络,表示在 192.168.x.x 的所有网络均可相互访问,若此时另一个网络 172.18.x.x 想要访问 192.168.x.x 时,是无法访问的。

1、将有172.18.x.x的网络与 mynet 相连
docker network connect mynet 容器名(即网络为 172.18.x.x 的容器)

2、再次查看网络情况
docker network inspect mynet
发现,实际上是将此容器加入到 mynet 网络中,即一个容器,两个IP。

3、测试是否能够 pingdocker exec -it 容器1 ping 容器2

4、创建镜像

注:可跳过,我们在创建容器时可指定镜像

我们一共需要创建如下镜像:

3、nginx : docker pull nginx:latest
4、Jenkins: docker pull jenkins/jenkins:latest

5、查看镜像
docker images

输出:
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
jenkins/jenkins   latest    c9101035cede   13 hours ago   478MB
nginx             latest    f5a6b296b8a2   5 days ago     187MB
hello-world       latest    9c7a54a9a43c   4 months ago   13.3kB

6、创建自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

5、创建容器和数据库

5.0、容器的挂载

注:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

我们挂载目录时,不要放在home下即使要放,需要管理员权限,或者命令前加sudo ,不然会出现莫名其妙启动不了的错误

  • 同时,我们可以将宿主机上需要挂载的文件夹进行提权。如果不提权,可能会导致容器挂载的文件夹有东西但因为宿主机无法写入导致宿主机文件夹为空反过来使容器里面的文件夹也为空。
  • 其次,发现在使用nginx时即使将文件夹提升权限,创建后依然无文件,可能是我操作出错等等,但是还有方法,我们先创建好需要挂载的文件夹,然后创建nginx容器,注意此时不要挂载文件,创建好容器后将容器内对应文件夹内容复制到宿主机的对应需要挂载的文件夹中。然后删除容器,再次创建容器此时将挂载写上即可(注:这种方法只合适每次创建后内容都一样的容器)

5.1、安装Mysql

前言

以下内容只做参考,未实际使用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

注:被 = 框起来的无需操作,这里只是作为演示,非要做会发现,必须要将密码设置为123456才能成功,且在挂载时不能事先创建文件夹,且容器的文件夹需要对照官网给的例子进行映射
================================================
1、创建Mysql容器并运行
docker run -d \
  --name my-mysql-container \
  -e MYSQL_ROOT_PASSWORD=your_root_password \
  -e MYSQL_DATABASE=your_database_name \
  -e MYSQL_USER=your_mysql_user \
  -e MYSQL_PASSWORD=your_mysql_password \
  -v /myDocker/mysql/conf:/etc/mysql/conf.d \
  -v /myDocker/mysql/data:/var/lib/mysql \
  -p 3306:3306 \
  --net bridge \
  mysql:5.7

# docker run:用于启动一个容器。
#-d:表示在后台运行容器。
#--name my-mysql-container:给容器一个自定义的名称,这里是 "my-mysql-container",你可以根据需要更改它。
#-e MYSQL_ROOT_PASSWORD=your_root_password:设置 MySQL 的 root 用户密码。将 "your_root_password" 替换为你想要的密码。
#-e MYSQL_DATABASE=your_database_name:创建一个新的数据库并设置其名称。将 "your_database_name" 替换为你想要的数据库名称。
#-e MYSQL_USER=your_mysql_user 和 -e MYSQL_PASSWORD=your_mysql_password:可选的,用于创建一个新的 MySQL 用户并设置其密码。将 "your_mysql_user" 和 "your_mysql_password" 替换为你想要的用户名和密码。
#-v /path/to/your/mysql/data:/var/lib/mysql:这是挂载数据卷的部分。将 "/path/to/your/mysql/data" 替换为你本地系统上存储 MySQL 数据的目录路径。这将使 MySQL 数据在容器停止或删除时仍然保留在本地系统中。
#-p 3306:3306:将容器的 MySQL 端口(默认为 3306)映射到主机的相同端口,以便可以通过主机访问 MySQL 服务。
# --net bridge :指定网络
2、进入容器内部
docker exec -it mysql /bin/bash


docker exec -it mysql mysql -u root -p(直接登陆)

3、登陆
mysql -uroot -p123456

4、退出
exit (Ctrl+D)
========================================

分割线====

上述只是用来显示并非实际使用,如下则是实际教程、注Mysql并未部署在容器中,而是直接在Linux系统上使用。

1、查找已安装的MySQL软件包和CentOS7下还需要查找是否存在mariadb包:
rpm -qa|grep mysql
rpm -qa|grep mariadb
若存在包,则删除、没用则不用执行。没有输出即无包
rpm -e --nodeps mysql-libs-5.1.73-1.el6.x86_64
rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64

2、提升权限,由于 MySQL 安装过程中,会通过 MySQL 用户在 /tmp 目录下新建 tmp_db 文件,所以需要给 /tmp 目录较大的权限
chmod -R 777 /tmp

3、检查依赖
rpm -qa|grep libaio
rpm -qa|grep net-tools
若不存在,则安装对应依赖
yum -y install libaio net-tools

4、安装
先进入opt目录
cd /opt

5、使用 wget下载并解压,在下载的过程中会显示进度条,包含 (下载完成百分比,已经下载的字节,当前下载速度,剩余下载时间)
wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-1.el7.x86_64.rpm-bundle.tar
tar -xvf mysql-5.7.16-1.el7.x86_64.rpm-bundle.tar

6、解压并安装
当执行上述命令且下载完成后,会自动出现一行解压命令,此时我们只需回车即可
安装:
解压后会有若干包,但我们只需使用其中一部分,安装如下包
rpm -ivh mysql-community-common-5.7.16-1.el7.x86_64.rpm 
rpm -ivh mysql-community-libs-5.7.16-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.16-1.el7.x86_64.rpm 
rpm -ivh mysql-community-server-5.7.16-1.el7.x86_64.rpm
注意:1. 安装 server 会比较慢;
   2. 如果前面第 1.3 步没检查好,在安装 mysql-community-server 会报错

7、初始化 Mysql
mysqld --initialize --user=mysql

8、查看并记住密码、“root@localhost:” 后面的就是初始化密码,要记下来,后面连接数据库会用到
cat /var/log/mysqld.log | tail -n 10

9、启动 MySQL 服务
systemctl start mysqld.service

10、查看是否自启动
systemctl list-unit-files|grep mysqld.service
若输出:mysqld.service                                enabled 
则设置自启动
systemctl enable mysqld.sercice

11、登陆
mysql -uroot -p刚才记下的密码
出现:Welcome to the MySQL即为登陆成功,若出现错误,看密码是否正确,其中若密码中存在需要转义的字符需要使用英文双引号括起来,如:ssdd"("ddd

12、修改密码:因为初始密码为临时,会过期
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的密码';
注:
1、复制时不要带 ; 因为带了会直接执行,不方便修改密码,当输入完成后需要添加上 ; 否则mysql以为你没有输入完。
2、密码太过简单会报错ERROR 1819 (HY000):
解决方法:
set global validate_password_policy=LOW; // 设置密码的验证强度等级为低(LOW)
set global validate_password_length=6; // 设置密码长度为6,最小为4

13、修改字符集
输入以下语句可以发现数据库和服务端的默认字符都是latin1,如果不修改容易出现乱码
show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
解决方法:
输入 "vim /etc/my.cnf " 或用Xftp打开 "/etc/my.cnf " 文件进行编辑,在最后加上
character_set_server=utf8
init_connect=’SET NAMES utf8’

14、重启Mysql服务
systemctl restart mysqld

15、远程访问
输入以下语句查看MySQL的用户信息:
select host,user,authentication_string from mysql.user
输出:
+-----------+-----------+-------------------------------------------+
| host      | user      | authentication_string                     |
+-----------+-----------+-------------------------------------------+
| localhost | root      | *514C5DC7D34822064704BE6926512A4A84BC1677 |
| localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
+-----------+-----------+-------------------------------------------+
#发现都是localhost,即本地访问
#host:表示连接类型
#%:表示所有远程通过 TCP方式的连接
#IP地址:如 (192.168.1.2,127.0.0.1) 通过制定ip地址进行的TCP方式的连接
#机器名:通过制定i网络中的机器名进行的TCP方式的连接
#::1:IPv6的本地ip地址 等同于IPv4的 127.0.0.1
#localhost:本地方式通过命令行方式的连接 ,比如mysql -u xxx -p 123xxx 方式的连接。
#user:表示用户名
#同一用户通过不同方式链接的权限是不一样的。
#authentication_string:密码
#所有密码串通过password (明文字符串)生成的密文字符串。加密算法为MYSQLSHA1,不可逆。MySQL 5.7的密码保存到#authentication_string字段中不再使用password字段(在5.5中使用)。
15.1、因此下面给出了用户授权、创建用户、删除用户和修改密码的命令。
用户授权命令(该命令执行授权时如果发现没有指定的用户,则会直接创建一个新用户来完成授权):
grant 权限1,…权限n on 数据库名.表名 to 用户名@用户地址 identified by ‘密码’;
例如,授予通过网络方式登录的root用户,有对所有库、所有表的全部权限,密码设为”newpwd123”:
grant all privileges on *.* to root@'%' identified by 'newpwd123';
15.2、测试访问,就不讲了
注:记得将3306端口开放,如果是腾讯云就在安全组中添加规则,然后使用tcp:3306开放端口

16、补充知识
16.1、查看Mysql版本 
mysqladmin -u root -p密码 –version 

16.2、关闭Mysql服务
systemctl stop mysqld.service

16.3、查看mysql服务状态
systemctl status mysqld

16.4、连接数据库后修改数据库的字符集(其中mydb为数据库名)
alter table mytbl convert to character set 'utf8';

16.5、修改数据库表的字符集(其中mytbl为表名)
alter table mytbl convert to character set 'utf8';

16.6、创建Mysql用户
create user root identified by '123abc';

16.7、修改用户名
update mysql.user **set** user='li4' where user='wang5';
flush privileges;  # 所有通过user表的修改,必须用该命令才能生效。

16.8、删除用户
drop user user@host;

16.9、修改当前用户的密码
set password = password('new_password')

16.10、修改某个用户的密码
update mysql.user set password=password('new_password') where user='name';
flush privileges; # 所有通过 user表的修改,必须用该命令才能生效。

相关目录介绍

在这里插入图片描述

5.2、安装redis

1、下载:版本可以选择其他
wget http://download.redis.io/releases/redis-5.0.7.tar.gz

2、解压、注意解压的目录,最好新建一个
cd /redis
tar -zxvf redis-5.0.7.tar.gz

3、安装gcc依赖环境
yum install gcc

4、编译与安装,这里可以在 cd /redis/redis-5.0.7
#切换到 redis-5.0.7 目录
cd /redis/redis-5.0.7
# 编译
make
# 安装
make install
默认安装路径为/usr/local/bin目录

5、后台启动
Redis默认是无法进行后台启动的,需要修改配置文件
cd /redis/redis-5.0.7
找到 redis.conf 文件并打开
在文件中查找:daemonize 
发现其后跟着 no,我们将其修改为 yes,即:daemonize yes,然后保存
最后启动:
cd /usr/local/bin
redis-server /redis/redis-5.0.7/redis.conf
使用命令 ps -ef |grep redis 查看进程是否启动
输出为:
root      6370     1  0 16:56 ?        00:00:00 /usr/local/bin/redis-server *:6379
root      6384  2098  0 16:56 pts/0    00:00:00 grep --color=auto redis
或者使用客户端测试:输入命令
redis-cli
然后输入:ping,输出为 PONG 即可

6、开机自启动设置
6.1、新建目录
mkdir -p /etc/redis   用于存放redis的配置文件(一般将原来的配置文件复制一份出来)
mkdir -p /var/log/redis 用于存放redis的日志文件
mkdir -p /var/redis/6379 用于存放redis的持久化文件(6379表示redis实例的端口号)

6.2、将 redis.conf 配置文件(在/redis/redis-5.0.7下)复制到 /etc/redis 下并重命名为 6279.conf

6.3、修改6379.conf内容
- 注释掉bind 127.0.0.1
- daemonize no  → daemonize yes
- logfile "/var/log/redis/6379.log" (注:查找logfile,并将其替换为此,下面的也一样)
- dir /var/redis/6379
- requirepass redis的密码 (注:这里可以设置密码,记得将注释取消)

6.4、将redis解压后的目录中的utils下面的redis_init_script文件复制到/etc/init.d下面,并重命名为redis_6379

6.5、修改redis_6379文件 (注:正常情况下无需改动,观察一下即可)
#这个类似一个定义,这边的定义需要和使用的redis启动的使用的配置文件名字保持一致(不要后缀名)
REDISPORT=6379
#使用的配置文件。这边就是去读取/etc/redis下面的“6379.conf“配置文件
CONF="/etc/redis/${REDISPORT}.conf"
就需要修改以上两个配置

6.6、将redis_6379服务设置为开机自启动
chkconfig redis_6379 on

6.7、重启,查看进程 ps -ef |grep redis 

7、打开与关闭命令 : 这里的 redis_6379 为/etc/init.d下面,重命名为redis_6379的文件名,可自行替换
# 打开redis命令:
service redis_6379 start

# 关闭redis命令:
service redis_6379 stop

8、设置密码后登陆
照成运行:
cd /usr/local/bin
redis-cli
发现可以,但是此时随意输入命令发现无法运行,此时我们有两种方法
- 已经运行 redis-cli 的情况下 ,我们输入 auth redis的密码
- 未运行 redis-cli 的情况下 ,我们输入 redis-cli -a redis的密码
返回 OK 则表示成功

6、Docker部署Nginx

1、下载
docker pull nginx

2、创建挂载的文件夹,(但第一次创建容器不进行挂载,而是先创建容器然后将容器里需要挂载的文件复制到我们在Linux上真实的文件夹)
注:如果直接挂载,由于linux下的文件夹都为空会导致容器内也变成空
# 创建挂载目录
mkdir -p /home/nginx/conf
mkdir -p /home/nginx/log
mkdir -p /home/nginx/html
mkdir -p /home/nginx/ssl

- /home/nginx/conf
	存放nginx的配置信息
- /home/nginx/log
	存放日志信息
- /home/nginx/html
	存放你的前端网页
- /home/nginx/ssl
	如果想使用https,就需要这个文件夹,存放证书
	
# 提升权限
chmod 777 -R /home/nginx/conf
chmod 777 -R /home/nginx/log
chmod 777 -R /home/nginx/html
chmod 777 -R /home/nginx/ssl

3、创建容器并复制到宿主机
# 生成容器
docker run --name nginx -p 80:80 -d nginx
# 将容器nginx.conf文件复制到宿主机
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /home/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /home/nginx/

4、删除创建的容器
# 找到nginx对应的容器id
docker ps -a
# 关闭该容器
docker stop nginx
# 删除该容器
docker rm nginx
 
# 删除正在运行的nginx容器
docker rm -f nginx

5、再次创建容器,此时加入挂载文件夹以及自定义网络,加入自定义网络后容器间才能直接访问,这样前端才能访问后端
docker run \
    -p 80:80 -p 443:443 \
    --name nginx \
    -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
    -v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
    -v /home/nginx/log:/var/log/nginx \
    -v /home/nginx/html:/usr/share/nginx/html \
    -v /home/nginx/ssl:/etc/nginx/ssl \
    --net mynet \
    -d nginx:latest
# 注:这里创建时还映射了443端口,如果想通过https+域名访问,这个是必不可少的!!!!!!!!! 
    

7、进入容器,更新nginx
//修改nginx配置,在不能重启的情况下,可以无需重新启动Docker容器即可重新加载新配置。Nginx可以hot-reload配置而不重新启动。
//查询nginx所在容器id:docker ps -a
docker ps -a
//测试nginx配置
docker exec 容器id nginx -t 
//重新加载nginx配置
docker exec 容器id  nginx -s reload 
# 注:上述可能刷新失败,因为其要等到无连接后才能够刷新

6.1、配置文件原理介绍

这个之所以拿出来讲,是因为是重点也是难点,接下来会一步步慢慢讲!

原理介绍,可跳过,后面会有详细配置信息

首先,我们开启nginx后且可以直接通过IP地址访问到nginx页面时,表示初步部署成功!

但是,还有若干问题:

1、 如果你的宿主机的端口号设置的不是80,那么在进行IP访问时一定要加上端口号才能访问。
像这样:`-p 80:80` ,设置时才不需要端口号直接使用IP访问。同时需要nginx开启端口监听

我的需求是,公网IP是唯一的,但是会有若干域名指向此地址,且不同域名表示不同的前端项目,如何实现呢?

在实现之前,我们要了解一下配置文件某些东西的作用,下面是默认配置文件(default.conf)的内容,它在创建是就被我手动挂载到了/home/nginx/conf/conf.d 下。(注:我将注释的代码全部去除,方便讲解)

server {
    listen       80; # IPV4类型的监控容器内的80端口,由于我宿主机也设置为80,两者结合才是无需使用端口号的原因
    listen  [::]:80; # IPV6类型的监听80端口
    server_name  localhost; # 重点,下面讲

	# 当请求地址只有IP时,会走这里
    location / {
        root   /usr/share/nginx/html; # 此用处为,会去容器下的这个目录寻找目标文件
        index  index.html index.htm; # 如果目标文件知道了,就不需要执行此处,若未找到,则在目标目录下下载是否有名为index.html index.htm 的文件,有则返回,无则404.由请求于只有IP,没有带其他目录所以一定会走这里。
    }

	# 当请求来了之后但是由于某些原因导致发生500等5开头的错误,会走这个
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

很显然,这只是一个server结果,完整的配置文件不止这些,在 /home/nginx/conf/ 下有一个nginx.conf文件,两者组成形成完整的配置文件。

2、在我们初始的配置文件中有这个设置server_name localhost;,文件地址为 /home/nginx/conf/conf.d、我们明明使用的公网IP,但这里默认文件的设置却为本机地址,那为啥那个访问成功呢?

先说说一个请求到 nginx 容器并进行转发的全过程:

​ 首先若使用公网IP进行访问,43.126.94.119 因为无论宿主机还是nginx容器,进行端口映射的值都为80,且nginx设置了端口监听 listen 80; ,所以可以不添加端口号直接使用IP进行访问。

​ 由于有端口映射,所以这个请求会直接进入nginx,此时

server 模块中的 server_name 发挥作用,会从请求头中的 Host 获得值,可以是域名也可以是 IP ,

若是IP

则 会与所有server 模块中 server_name 的值进行比较,若有就转发给对应 server 模块,若无就会走默认的server 模块,

何为默认模块?即 server 中设置了这个参数 listen 80 default_server;,如果如果所有都没设置,会默认走第一个。

若是域名

同样进行域名匹配,若无,则走默认模块或者默认模块也无则走第一个模块

注:当你使用IP访问,但所有 server 中的 ``server_name 值都为域名时,此时server_name 失效,会走默认模块或者第一个

server_name 值的三种情况

  • localhost
  • 域名
  • IP
依据上述原理,我们实现简易版的请求转发,有几种情况

情况一:
当我们使用公网IP访问,此时有两个 server模块
- 第一个模块的 server_name 值为:localhost,有一个 location / {}模块,即简写版
 server_name  localhost; # 重点,下面讲
    location / {
        
    }

- 第二个模块的 server_name 值为:43.137.94.117,有一个 location / {}模块,即简写版
 server_name  43.137.94.117; # 重点,下面讲
    location / {
        
    }
若请求地址为 43.137.94.117 时 会走第 二 个模块 (因为模块二匹配成功)

情况二:
同样两模块,但此时location不同
- 第一个模块的 server_name 值为:localhost,有一个 location / {}模块,即简写版
 server_name  localhost; # 重点,下面讲
    location / {
        
    }

- 第二个模块的 server_name 值为:43.137.93.117,有一个 location / {}模块,即简写版
 server_name  43.137.94.117; # 重点,下面讲
    location ^~/gw {
        
    }
若请求地址为 43.137.94.117 时 会走第 1 个模块 (因为模块都匹配不成功,且无默认模块,所以走第一个)
若请求地址为 43.137.94.117/gw 时 会走第 2 个模块 (因为 模块二 匹配成功,所以走第二个)

注:^~/gw 表示无论/gw前面是啥都进行匹配

行文至此,依旧没有阐述如何在I域名不同但都指向同一IP下,访问不同域名可进入不同项目。

但实际上已经说了。

使用 server_name 的特性,将其值设置为不同域名即可

6.2、配置https与域名进行访问

1、首先,我们得判断nginx是否能够部署ssl,查询方法

进入nginx容器,cd /sbin 目录下,运行 nginx -V 命令,查看输出,若输出中存在:docker exec -it nginx /bin/bash 表示能够部署,若没有,则需要先安装,安装方法自行了解,我使用的容器nginx里面是自带的,不用额外配置

2、获取ssl证书,腾讯云有免费的ssl证书,申请后,然后到我的证书界面,选择右边的下载,选择Linux下nginx的下载,会获得一个压缩包,解压后有4个文件,然后将4个文件全部复制到服务器我们刚才创建的ssl目录下。

3、配置配置文件

在腾讯云我的证书那一块,右边有一个部署,点进去有在linux下的nginx如何部署https的教程。可以一步步对照

我们在 /home/nginx/conf/conf.d 目录下创建一个配置文件 gw.conf ,文件内容如下:

# 处理https请求的模块
server {
	listen 443 ssl; #ssl,监听端口

	server_name lvguidizi.com; # 域名
              
    ssl_certificate /etc/nginx/ssl/lvguidizi.com_bundle.crt; # 容器路径下的ssl文件夹下的.crt文件
    ssl_certificate_key /etc/nginx/ssl/lvguianzi.com.key;# 容器路径下的ssl文件夹下的.key文件
   
   # 下面的 4 行按照腾讯云教程来,个个教程有可能有差异,所以哪里的服务器用哪里的教程
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3; 

	ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
    ssl_prefer_server_ciphers on;
  
	# 我们做一个跳转,当通过域名访问时,将其跳转到 https://域名/gw 下,当然,你也可以不这样做
	location / {

		# 这意味着任何访问网站根目录的请求都会被重定向到 https://lvguidianzi.com/gw 这个 URL。
		rewrite ^/(.*) https://lvguidizi.com/gw;

	}

    # ^~/gw:表示无论/gw前面是啥只要后面以这个结尾都会进入这里,
    # 作用,会去你root设置的文件夹下寻找你location设置的/gw文件夹,并在文件夹下寻找你index设置的 indez.html文件
	location ^~/gw {

		  # 这个块处理以 /gw 开头的 URL 路径的请求。它使用 try_files 指令尝试寻找匹配的文件,如果找不到文件,则会重定向到 /gw/index.html; 页面。
		  # 这个块还设置了 root 和 index 指令,以指定根目录和默认索引文件。
		  try_files $uri $uri/ /gw/index.html;
		  root /usr/share/nginx/html;
		  index index.html;
	}

	# 这个用来做动静分离,相当于此路径下存放图片和一些其他文件
	# 同样,他会去 root+location的路径下找,相当于/usr/share/nginx/html/file/
	location /file/ {

	  root	/usr/share/nginx/html/;
      autoindex      on; # 列出访问目录
	}
	
	
#location ^~/openApi/ {
#  proxy_pass      http://172.16.0.12:9999/openApi;
#  proxy_set_header Host $host; # 这个指令设置了请求头中的 "Host" 字段,将其值设置为客户端请求中的 "Host" 值。这是为了确保后端服务器能够正确识别客户端请求的主机名。
#  proxy_set_header X-Real-IP $remote_addr; # 这个指令设置了一个自定义请求头 "X-Real-IP",将其值设置为客户端请求的真实 IP 地址。这可以帮助后端服务器获取客户端的真实 IP 地址。
#  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 这个指令设置了另一个自定义请求头 "X-Forwarded-For",将其值设置为 $proxy_add_x_forwarded_for,它包含了所有中间代理服务器的 IP 地址。这有助于追踪请求经过的代理服务器链。
#  # 这两个指令用于配置 Nginx 内部的请求头哈希表的大小。这些配置项通常不需要手动设置,除非您在配置文件中有特殊的需求。
#  proxy_headers_hash_max_size 512;
#  proxy_headers_hash_bucket_size 64;
#}


#location ^~/api/ {
#  proxy_pass      http://172.17.0.1:8081/;
#  proxy_set_header Host $host;
#  proxy_set_header X-Real-IP $remote_addr;
#  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#  proxy_headers_hash_max_size 512;
#  proxy_headers_hash_bucket_size 64;
#}

error_page  404    /404.html;

  # 这个指令指定了处理状态码 497 的方式。状态码 497 表示客户端应该将请求转发到另一个地址,通常是由于客户端请求协议与服务器配置的协议不匹配。在这里,当发生状态码 497 时,
  # Nginx 会将请求重定向到 https://$host$uri?$args;,这意味着它将使用相同的主机名和请求 URI 重新发送请求,但使用 HTTPS 协议。
  error_page 497  https://$host$uri?$args;
  error_page  500 501 502 503 504  /50x.html;
  # 这个 location 块定义了 /50x.html 页面的位置。它告诉 Nginx 在根目录的 html 子目录下寻找 50x.html 文件。这是用于定义错误页面的位置。
  location = /50x.html {
         root   html;
}

}   

# 处理http请求的模块
server {
        listen       80;
        listen  [::]:80;

        server_name lvguidizi.com;

        
        location / {
			# 当我们以http+域名方式进行访问时,会走到这里,然后会将http转换为https重新请求,就会回到上面的模块了
			return 301 https://$host$request_uri; 

        }  
 
}
# 处理公网IP的请求
server {
        listen       80;
        listen  [::]:80;

        server_name 43.136.9.118;

        
        location / {
			# 如果是公网IP访问,如果没有进行出来就会走默认模块,也就是nginx自动创建的第一个配置文件,也就是我们部署好nginx时访问网页会出现的 welcome to nginx。所以我们也需要跳转,
			return 301 https://lvguidizi.com/gw;
		

        }  
 
}

配置文件设置好后,我们需要在html文件夹下新建一个gw文件夹并创建一个index.html文件,然后就可以通过https://域名方式测试访问了,同时,我们也可以将打包好的vue项目放入gw文件夹下,就会自动访问了。

注:如果你觉得都配置好了但无法访问,可能有以下原因:

1、你的服务器443端口未开放(腾讯云是开放安全组),或者说你的nginx容器的443端口未映射(两者都要有)

2、你的ssl证书没用绑定到域名。

3、你的域名没用绑定到你的服务器公网IP

4、你的域名没有备案

5、配置文件完成后需要刷新nginx

6、配置文件中ssl证书名字或者路径设置错误,记得是容器路径

7、你的配置文件中 location 和root 模块组成的访问路径与你实际请求路径不同

6.3、配置同一域名部署多vue项目

假设有a,b两个vue项目。

1、在a项目的路由文件中进行如下配置(就是vue存放路由跳转的文件):

// 如果你的路由配置文件中没有这个,就新添一个
export default new VueRouter({
  base:'/a/', // 相当于在每一个路由跳转的路径前面加一个/a/路径
  }

2、在项目b也加入如上配置,只不过 base:'/a/' 改为 base:'/b/'

3、如果是vue2就在 config文件夹下的 index.js 下配置如下东西(b项目也记得按照规则改变):

...
build: {
assetsPublicPath: '/a/', // 将这个变量设置为你在路由上设置的路径,记得一致,这个是配置公共资源访问路径的选项,因为你的vue项目不在根目录下了,所以这里也要变
}
...

4、修改nginx配置文件

# 增加一个 location
location ^~/a {

		  try_files $uri $uri/ /a/index.html;
		  root /usr/share/nginx/html;
		  index index.html;
	}
location ^~/b {

		  try_files $uri $uri/ /b/index.html;
		  root /usr/share/nginx/html;
		  index index.html;
	}

5、在nginx的html目录下,就是存放vue项目的根目录。创建两个文件夹a,b然后在文件夹下存放vue项目,然后刷新配置文件。

6、附加:因为vue项目会访问后端,如果是springboot,此时我们需要在nginx里增加一个代理。(题主不清楚是不是一定要,但是题主使用若依的前端vue是必须要这样才能访问后端。正常情况下直接输入后端地址是可以访问到的,但是若依的前端加上去后就不能通过前端访问后端了)

# 这个路径 /prod-api/ 是要与前端vue项目里面的一致
location ^~/prod-api/ { 
  proxy_pass      http://172.16.0.12:9999/; # 你的公网IP或者内网IP加上后端的端口号
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_headers_hash_max_size 512;
  proxy_headers_hash_bucket_size 64;
}

前端若依里面有个文件 .env.production ,里面有如下代码:

# 页面标题
VUE_APP_TITLE = 若依管理系统

# 生产环境配置
ENV = 'production'

# 若依管理系统/生产环境
VUE_APP_BASE_API = '/prod-api' # 这个就是要与nginx里面一致的东西了

7、docker部署 Jenkins

!!!!!!!!!!!!!!!!!!!重难点!!!!!!!!!!!!!!!!!!!!

如果单纯按照网络教程来,会逐渐迷惑,甚至100个教程有一百种方法。。。

首先,我们讲一下为啥需要在 Docker 里面使用 jenkins ?

因为方便,jenkins配置啥的很多,新手一不小心就错了,此时如果在宿主机上,就很难去一键清零,但是Docker不一样,将容器删除再创建就又是一条好汉了。

其次,接下来教程默认你已经安装好docker了,话不多说开干!

前言:自动化部署流程

首先,我们创建运行jenkins容器,然后登陆jenkins,设置好gitee,jdk,maven,ssh等等。记得在我们的项目的根目录(如果是多模块项目,就在启动模块的根目录)下创建Dockerfile文件,然后就是创建maven项目,在项目设置里,设置好需要git的文件路径,然后设置需要打成jar包的模块。然后设置shell语句。

- gitee:存放我们的项目代码,
- jdk,maven:打成jar包需要的环境,jenkins自带jdk,但如果是最新的jenkins是jdk11,所以要么我们创建容器时控制为jdk8的版本要么在jenkins的系统设置里面手动修改(此修改需要在宿主机安装jdk,比较麻烦),maven是没有自带的,需要我们手动安装或者自动安装,没啥区别。
- ssh :推送,相当于将我们创建好的jar推送到指定服务器上运行,因为是在容器里面生成的jar包,
- Dockerfile文件:用来创建我们项目的docker镜像,只有创建镜像才能依据镜像创建容器,才能运行jar包



1、在jenkins中我们需要挂载某些文件,但是如果你挂载在宿主机的文件夹没用权限,那么g了,当你挂载创建完成后,会发现文件夹空无一物。所以我们需要在宿主机下先创建文件夹。然后提升文件夹权限。
mkdir -p /common/jenkins_home # 创建文件
chmod 777 -R /common/jenkins_home # 提升权限
chmod 777 -R /var/run/docker.sock # 下面两个权限提升是以防万一,这两个文件夹作用等下说
chmod 777 -R /usr/bin/docker

2、让Jenkins 容器里面能够使用宿主机的 docker 命令
在自动化部署时,我们在执行容器,镜像创建时是在jenkins里面的,但是正常情况下jenkins容器里面用不了容器外的docker命令,所以我们这里将docker命令需要的东西进行映射一下,也就是挂载。所以先将用到的文件夹提升权限,怕需要。需要挂载的文件夹有这两个:
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \

3、创建并运行jenkins容器
docker run -d  -p 8080:8080 -p 50000:50000 \
--net mynet --restart=on-failure \
-v /common/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
--name jenkins jenkins/jenkins:lts-jdk8
# 解释:
-p 8080:8080:
	端口8080用于Jenkins的Web界面
-p 50000:50000
	用于Jenkins的Slave节点通信。Slave节点是用于执行构建作业的工作节点。
	
--net mynet:这个是我自己创建的自定义网络,容器间通信使用

--restart=on-failure: 这部分指定了容器在失败时应该自动重启。如果Jenkins容器崩溃或失败,Docker将尝试重新启动它。

-v /common/jenkins_home:/var/jenkins_home \:就是查看jenkins初始密码和一些其他文件,所以需要挂载

-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \:这两个是运行docker命令需要的

--name jenkins:指定容器名字

jenkins/jenkins:lts-jdk8:指定自带jdk版本为8

运行 docker ps 命令,如果在运行的容器列表找到了jenkins表示创建并运行成功!
CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                                                                                      NAMES
7ad88fe4f57b   jenkins/jenkins:lts-jdk8   "/usr/bin/tini -- /u…"   27 hours ago    Up 27 hours    0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp   jenkins         

4、通过服务器加端口访问jenkins:如119.168.1.3:8080,服务器就是你自己的公网IP,端口号是创建时设置的。

5、等它加载会,会让你输入密码,这个秘密存在的地址会在网页上显示,可以通过路径打开文件获取

6、密码输入完后会有两个选择,安装推荐的插件和选择插件来安装。我们选择安装推荐的插件,然后就是等待下载完成

7、会显示让你创建第一个用户,一次填写好并记下来,后面会用到。

好,下面就需要图文并茂了:

7.8、先下载插件,登陆后选择左边的 Manage Jenkins 选项,就是带一个小齿轮的,相当于设置,然后下滑选择 Manage Plugins

在这里插入图片描述

在这里插入图片描述

7.9、分别下载如下三插件,Maven Integration,, gitee,Publish Over SSH,下面输入框里面是简写,也能找到,第二张图是找到后勾选然后点击不重启安装

在这里插入图片描述

在这里插入图片描述

7.10、点击全局设置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

私人令牌 - Gitee.com

注意:私人令牌记得保存下来,获得后回到jenkins,将令牌输入,下面的ID和描述不用填,直接保存,然后就和我的一样有一个选项了,直接选择

在这里插入图片描述

7.11、SSH

在这里插入图片描述

在这里插入图片描述

其余的保持默认即可

然后返回设置,这次点击第一行的中间那个

在这里插入图片描述

7.12、设置 Global Tool Configuration 开头的maven和jdk都不用管,我们找到下面的maven

在这里插入图片描述

7.13、创建maven项目

这里就正式开始制作自动化部署了,在制作之前,我们需要先准备一点东西。

1、在代码项目的根目录下,或者多模块项目的启动模块的根目录下创建一个制作代码项目镜像的文件:Dockerfile

注:记得将此文件上传至 gitee

在这里插入图片描述

FROM java:openjdk-8u111
VOLUME /tmp
ADD target/ruoyi-admin.jar ruoyi-admin.jar
EXPOSE 9999
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
ENTRYPOINT ["java","-jar", "$JAVA_OPTS","/ruoyi-admin.jar"]

- FROM java:openjdk-8u111 :
	基础镜像是 java:openjdk-8u111,表示基于 OpenJDK 8u111 版本的 Java 运行时环境。
- VOLUME /tmp  
 	在容器内创建一个临时卷,通常用于存储临时文件或持久化数据。
- ADD target/ruoyi-admin.jar ruoyi-admin.jar
	将宿主机上的 target/ruoyi-admin.jar 文件复制到容器内,并命名为 ruoyi-admin.jar。因为jar包在此文件运行前就创建好了,jar创建的设置在下面会讲到。
	为什么地址是 target/ruoyi-admin.jar?
	因为在下面的设置及其运行结果看,在执行这几行代码前,整个项目已经处于workspace/ruoyi-admin/下了。workspace是jobs/目录下的一个文件夹。 jobs 是jenkins专门用来存放创建好的maven项目。里面包含项目相关的东西
- EXPOSE 9999
	就是你代码项目启动需要的端口号
- ENV TZ=Asia/Shanghai 
	时区
- ENV JAVA_OPTS="-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
	初始堆内存大小,最大堆内存大小,元空间初始大小,元空间最大,若超出则垃圾回收
- ENTRYPOINT ["java","-jar", "$JAVA_OPTS","/ruoyi-admin.jar"]
	定义容器启动时要执行的命令。它启动了一个 Java 进程,运行 ruoyi-admin.jar

2、正式创建maven项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

点击添加,配置用户名和密码

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

命令:

clean install -pl ruoyi-admin -am -amd

# 一般写上面就行,下面是补充

clean package  -pl  ruoyi-admin -am -amd   -P test -Dmaven.test.skip=true
clean package 清除打包
-pl ruoyi-admin -am -amd 指定项目下的子模块
ruoyi-admin 是子模块的项目名
-P test 指定构建环境,项目配置文件的名字
-Dmaven.test.skip=true 跳过maven测试

在这里插入图片描述

在这里插入图片描述

下面的表示当项目的jdk,maven都准备好了,jar也打好了之后要执行啥东西,此时也就是开始先清除之前旧东西(如果有),然后开始运行 Dockerfile 文件创建镜像,然后通过镜像创建容器,然后运行容器,然后查看容器是否运行,之后就部署好了

请添加图片描述

这里的shell代码为

docker stop ruoyi-admin || true 
docker rm ruoyi-admin || true
docker rmi ruoyi-admin || true
docker build -t ruoyi-admin ruoyi-admin/
mkdir -p common/logs/ruoyi-admin
chmod 777 -R common/logs/ruoyi-admin
docker run -d -p 9999:9999  -v /common/logs/ruoyi-admin:/home/ruoyi/logs --net mynet --name ruoyi-admin ruoyi-admin

# 解释:
- docker stop ruoyi-admin || true 
	如果有旧容器就停止,没有就返回true,继续
	
- docker rm ruoyi-admin || true
  docker rmi ruoyi-admin || true
	同上,有就删除容器与镜像
	
- mkdir -p common/logs/ruoyi-admin
chmod 777 -R common/logs/ruoyi-admin
	创建文件夹和提升权限
	
- docker build -t ruoyi-admin ruoyi-admin/
	这个命令从位于ruoyi-admin/目录中的Dockerfile构建一个名为ruoyi-admin的Docker镜像,并使用-t选项为镜像指定名字。
	以workspace文件夹为始
	
- docker run -d -p 9999:9999  -v common/logs/ruoyi-admin:/var/logs --link redis:redis --link mysql:mysql --net mynet --name ruoyi-admin ruoyi-admin
	-d:以后台模式运行容器。
    -p 9999:9999:将主机的9999端口映射到容器的9999端口。
    -v common/logs/ruoyi-admin:/var/logs:将主机上的common/logs/ruoyi-admin目录映射到容器的/home/ruoyi/logs目录,用于日志持久化。我使用的若依,它已经帮我配置好了日志文件,所以可以直接使用,如果是其他的项目需要自己在springboot项目里面创建logback.xml 去进行设置,具体百度
    --link redis:redis --link mysql:mysql:将容器连接到名为redis和mysql的其他容器。
    --net mynet:将容器连接到名为mynet的自定义网络。
    --name ruoyi-admin:为容器指定名称为ruoyi-admin。
    ruoyi-admin:指定要运行的Docker镜像。
===============================
如果想将此代码放入一个sh文件,由于win和linux差别,win创建*.sh文件是无法直接在linux下运行,需要将文件通过
chomd +x ./q.sh
命令,将sh变为可执行文件。

至此,所有配置完成,然后保存。回到开始页面,开始构建项目。初次构建会下载maven和jdk所以会慢。然后可以查看日志如果构建失败看看哪一步出错

8、杂项

1、导入字体文件方式

  • 使用nginx的动静分离,将字体文件放入其中,然后在项目中引用其路径,然后在nginx配置动静分离的配置文件中修改其location,增加一项:add_header Access-Control-Allow-Origin *;# 解决字体文件跨域问题
location /file/ {
	  root	/usr/share/nginx/html/;
      autoindex      on; # 列出访问目录
	  add_header Access-Control-Allow-Origin *;# 解决字体文件跨域问题
	}
	
  • 在存储在本地,发现可以访问到,但是网页会显示加载字体文件失败, 在.gitignore 文件中添加 *.ttf binary,即,你字体文件的后缀,这样就可以了,但是我不理解为啥可以…

注:这样确实可以成功,但是有个问题,字体文件比较大,小的几m大的10几m,对于网页访问来讲,加载很慢,影响用户体验,所以我们需要精简一下字体文件,将我们项目中没有用到的字体去除然后重新生成字体文件。

这里使用到 字蛛

无论是上面的哪种方法,都需要将字体包精简,而字蛛就是运作原理是:

新建一个index.html文件,在文件中导入我们自定义的字体以及若干文字,然后通过字蛛进行操作生成精简版的字体文件,这个文件里面的字体个数取决于你在html文件中写入的不同文字个数。

使用字蛛

1、确保你的node版本是16左右,字蛛使用需要的npm版本有一定要求,好像是6.9.0以上,这里我们通过安装nodejs去升级npm,

2、使用管理员权限打开cmd,并输入一下命令

npm install font-spider -g

如果保存查看两方面,是否为管理员启动,npm版本是否高于6.9.0.

3、为字蛛安装环境变量。一般情况下在nodejs安装目录下的 E:\nodejs\node_cache 目录有一个font-spider.cmd文件,我们找到这个路径,打开环境变量设置,设置系统环境变量中选择 path 新建一个,路径就选择 E:\nodejs\node_cache。然后确认。

4、我们随便在一个文件夹下,将自定义的字体文件放入这个文件夹下,然后在文件夹下创建一个index.html,文件,假设字体文件名为 a.ttf。那么在index.html文件下编写如下内容:

<!DOCTYPE html>
<html lang="en">
<style>
    @font-face {
        font-family: 'a';
        src: url("a.ttf") format('truetype');
        font-weight: normal;
        font-style: normal;
    }
</style>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    这里写出所有你想要的文字,字蛛会自动扫描这个文件里面的文字,然后基于你给的文字生成一个字体文件

</div>
</body>
</html>
<style>
    div{
        font-family: "a";
    }
</style>

然后使用管理员权限,打开cmd,并且切换目录到这个文件夹下。即存在字体文件a和index.html文件的文件夹。

然后执行命令:

font-spider index.html

经过一阵运行后你会发现,在文件夹下生成了一个文件夹 .font-spider,这个文件夹下存放的是你原来的字体文件a。而生成的新字体文件是在和 index.html 同级下,也是叫 a.ttf 即新文件覆盖了旧文件。然后我们就可以使用这个文件了,会发现这个文件大小变小了很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1053846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5G消息发展的前景与挑战

随着5G技术的快速发展和普及&#xff0c;5G消息正逐渐成为全球通信领域的新焦点。 随着5G技术的快速发展和普及&#xff0c;5G消息正逐渐成为全球通信领域的新焦点。 5G消息发展呈现规模化、产业化趋势 自2020年4月国内三大运营商联合发布5G消息白皮书以来&#xff0c;已经过…

Ubuntu20.04.1编译qt6.5.3版mysql驱动

下载qtbase6.5.3源码&#xff0c;将plugin中sqldrivers源码拷至于项目工程中&#xff0c;使用qtcreator打开文件 1、下载mysql开发库 sudo apt-get update sudo apt-get install build-essential libmysqlclient-dev 2、在msyql子目录中CMakeLists.txt第一行添加头文件、引…

面试必考精华版Leetcode236. 二叉树的最近公共祖先

题目&#xff1a; 代码(首刷看解析 10.1&#xff09;&#xff1a; class Solution { public:TreeNode* ansnullptr;bool FindSon(TreeNode* root,TreeNode* p,TreeNode* q){if(root nullptr) return false;bool lson FindSon(root->left,p,q);bool rson FindSon(root-&…

力扣 -- 712. 两个字符串的最小ASCII删除和

解题过程&#xff1a; 参考代码&#xff1a; class Solution { public:int minimumDeleteSum(string s1, string s2) {int ms1.size();int ns2.size();//求两个字符串的总ASCII和int sum0;for(const auto& e:s1){sume;}for(const auto& e:s2){sume;}//多开一行&#x…

数据结构与算法-(6)---栈的应用-(2)进制转换

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

基于STM32设计的智能化钻杆系统(华为云IOT)

一、项目引言 在现代石油、天然气等资源勘探和开采过程中,钻井是一项关键的工艺。为了提高钻井作业的准确性和效率,我们设计了一种基于STM32的智能化钻杆系统。该系统利用先进的控制和通信技术,实现了远程控制管子的转动和移动角度,并通过管子设备端的OLED显示屏显示接收到…

Docker从认识到实践再到底层原理(八)|Docker网络

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

WiFi网络分析工具Airtool for Mac

Airtool是一款Mac平台上的WiFi网络分析工具&#xff0c;它可以帮助用户监测、分析和管理无线网络。 以下是Airtool的一些主要功能和特点&#xff1a; 实时监测&#xff1a;Airtool可以实时监测当前Mac设备所连接的WiFi网络&#xff0c;包括网络速度、信号强度、连接状态等。信…

Linux CentOS7 vim重复行

在用vim编辑处理文件时&#xff0c;会有重复行。有的是情境需要&#xff0c;有的可能是误操作而形成。对于正常形成的重复行&#xff0c;我们不作讨论&#xff0c;我们仅讨论什么情况下会出现重复行&#xff0c;如何避免&#xff0c;如何处理。 在文件中的单行或多个连续空白行…

Docker从认识到实践再到底层原理(九)|Docker Compose 容器编排

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

每日一练-Q1-大数加法-20231001

目录 1.题目描述 2.输入描述 3.示例提示 4.问题分析 5.通过代码 1.题目描述 大数一直是一个c语言的一个难题。 现在我们需要你手动模拟出大数加法过程。 请你给出两个大整数加法结果。 2.输入描述 第一行输入整数n&#xff0c;第二行输入整数m。 (1<number<1e100)…

Leetcode 224. 基本计算器

文章目录 题目代码&#xff08;10.1 首刷看解析&#xff09; 题目 Leetcode 224. 基本计算器 代码&#xff08;10.1 首刷看解析&#xff09; class Solution { public:int calculate(string s) {stack<int> sk; // 存储正负号sk.push(1);int sign 1;int res 0;int i…

优维低代码实践:应用级配置

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

【Vue】Vuex详解,一文读懂并使用Vuex

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

一图带你了解封装与分用

一、前缀知识 IP地址&#xff1a;用于定位主机的网络地址。 端口号&#xff1a;区分主机上不同的应用程序。 协议&#xff1a;描述了网络通信传输的数据的含义。 二、TCP/IP五层网络模型 物理层&#xff1a;描述了网络通信中基础设施的规范。 数据链路层&#xff1a;相邻节点之…

fcntl函数 非阻塞轮询

fcntl&#xff08;&#xff09; 在打开的文件描述符 FD 上执行下面描述的操作之一。 操作由 cmd 确定。 fcntl&#xff08;&#xff09; 可以采用可选的第三个参数。 是否需要此参数由 cmd 确定。 所需的参数类型在后面的括号中指示。 每个cmd名称&#xff08;在大多数情况下&…

公众号迁移是什么?

公众号账号迁移的作用是什么&#xff1f;只能变更主体吗&#xff1f;微信公众平台的帐号迁移功能可将原公众号的粉丝、文章素材、违规记录、留言功能、名称等迁移至新的公众号。通过迁移可以实现公众号的公司主体变更、粉丝转移、开通留言功能、服务号转为订阅号等作用。因此不…

博弈论——劳资博弈

劳资博弈 0 引言 前一篇文章介绍了静态博弈中常见的几个案例以及场景&#xff0c;并且在此之前也还介绍过斯塔克尔伯格博弈等动态博弈&#xff0c;以及相关的解决方法——反应函数法。今天我们继续介绍一个常见的动态博弈——劳资博弈&#xff0c;并利用反应函数解决&#xff…

视觉人机器视觉线下培训遵循十大原则

1.​上课期间&#xff0c;自习时间没收手机&#xff0c;偷偷使用手机&#xff0c;将会被通报严重批评。 2.完善的教学设备&#xff0c;与具备现场落地设备要求。 3.教学与实操结合&#xff0c;老师教学的同时&#xff0c;要求你按照老师的效果&#xff0c;进行复现&#xff0…

黑马程序员RabbitMQ入门到实战教程【基础篇】学习笔记

目录 一、初始MQ 1.1、同步调用 1.2、异步调用 1.3、MQ技术选型 二、RabbitMQ 2.1、安装 2.2、收发消息 2.2.1、交换机 2.2.2、队列 2.2.3、绑定关系 2.2.4、发送消息 2.3、数据隔离 2.3.1、用户管理 2.3.2、virtual host 三、SpringAMQP 3.1、导入Demo工程 3…