培训第三十六天(docker应用,mysql容器应用,容器核对时间,容器之间的依赖 域名,文件联合系统,制作基础镜像,commit制作镜像)

上午

容器就是在镜像上添加了一个可写层

复制代码
 # 从镜像库中下载mysql镜像,mysql镜像是在基础镜像上加很多层制成的
 [root@docker ~]# docker pull mysql
 Using default tag: latest
 latest: Pulling from library/mysql
 6e839ac3722d: Pull complete 
 ad912193ad5f: Pull complete 
 25d13d87fd8d: Pull complete 
 004d383c75ef: Pull complete 
 6d9bbc82a0b8: Pull complete 
 81fec07ea550: Pull complete 
 83357cb2d3a5: Pull complete 
 8ffe968b82c1: Pull complete 
 30dfd9a7ed57: Pull complete 
 35844ae33cbe: Pull complete 
 Digest: sha256:86cdfe832c81e39a89cfb63c3fde1683c41cc00ef91e67653c9c1df0ba80f454
 Status: Downloaded newer image for mysql:latest
 docker.io/library/mysql:latest
 [root@docker ~]# docker images
 mysql        latest    a82a8f162e18   4 weeks ago   586MB
 centos       latest    5d0da3dc9764   2 years ago   231MB

回顾:

创建容器:docker run -it --name a1 centos:latest /bin/bash

查看容器:docker ps(查看正在up的容器)

docker ps -a(查看所有的容器)

切回宿主机:ctrl p q

启动容器:docker start a1

停止容器:docker stop a1

删除容器:docker rm a1

docker rm -f a1(强制删除容器)

如果容器正在运行,容器是无法删除的,如果容器没有删除,对应的镜像也无法删除

镜像的迁移:

save:docker save -o centos.tar centos:latest

load:docker load -i centos.tar

生成镜像:

export(通过容器生成tar包):docker export -o centos_httpd.tar a1

import(通过tar引入镜像):docker import -m httpd centos_httpd.tar centos:https

获得镜像的ip地址:

1、进入镜像的bash:yum -y install iprouter,net-tools

2、使用exec指令:dockers exec a1 yum -y install iprouter,net-tools

docker exec a1 ip add

3、直接使用inspect命令:docker inspoct a1

端口映射 -p:

docker run -it --name a2 -p80:80 centos:latest /bin/bash

docker run -it --name a2 -p80 centos:latest /bin/bash 宿主会指定一个大于32767的端口给容器

docker ps -a 查看实际给予的端口

docker run -it --name a2 -p10.0.0.101::80 centos:latest /bin/bash

数据持久化:

docker run -it --name a2 -v /zhenji:/rongqi centos:latest /bin/bash

1、使用容器部署一个考试项目

复制代码
 # 1、将资源上传到服务器
 [root@docker ~]# yum -y install unzip
 [root@docker ~]# unzip project_exam_system.zip 
 [root@docker ~]# ls
 project_exam_system.sql
 application.properties Project_ExamSystem-V1.0.0.war
 dist 
 # 2、创建基础镜像
 [root@docker ~]# systemctl  start docker.service
 [root@docker ~]# docker pull centos
 [root@docker ~]# docker run -it --name a0 centos:latest /bin/bash
 # 3、在容器中修改yum源
 [root@d02d68df46ac /]# rm -rf /etc/yum.repos.d/*
 [root@d02d68df46ac /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
 [root@d02d68df46ac /]# yum clean all && yum makecache
 # 4、在容器中安装epel
 [root@d02d68df46ac /]# yum -y install epel-release
 # 5、在容器中安装nginx
 [root@d02d68df46ac /]# yum -y install nginx
 # 6、ctrl p q退出容器
 [root@d02d68df46ac /]# read escape sequence
 # 7、导出tar包
 [root@docker ~]# docker export -o centos_nginx.tar a0
 # 8、引入tar包,成为镜像
 [root@docker ~]# docker import -m "nginx" centos_nginx.tar centos:nginx
 # 9、查看镜像
 [root@docker ~]# docker images
 # 10、删除容器
 [root@docker ~]# docker rm -f a0
 # 11、创建新的容器,在创建的同时指定端口,以及挂载目录
 [root@docker ~]# docker run -it --name a0 -p80:80/tcp -v /opt/:/usr/share/nginx/html centos:nginx /bin/bash
 # 12、在容器内部启动nginx服务
 [root@4a574dfa9e9a /]# nginx
 # 13、curl p q退出镜像
 [root@4a574dfa9e9a /]# [root@docker ~]# 
 [root@docker ~]# ls /opt
 containerd
 # 14、在宿主机上把dist目录中的文件复制到opt目录下
 [root@docker ~]# cp -r dist/* /opt/
 [root@docker ~]# ls /opt/
 assets  containerd  favicon.ico  index.html
 [root@docker ~]# curl localhost
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <link rel="icon" href="/favicon.ico">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Vite App</title>
     <script type="module" crossorigin src="/assets/index-C4kAShR5.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-CSz7ARPP.css">
   </head>
   <body>
     <div id="app"></div>
   </body>
 </html>
 # 15、浏览器查看并登录,查看错误信息

2、查找阿里云的镜像包

repo安装包下载_开源镜像站-阿里云 (aliyun.com)

下午

mysql下载路径:MySQL :: MySQL Community Downloads

1、使用mysql镜像创建并使用mysql容器

复制代码
 [root@docker ~]# docker images
 mysql        latest    a82a8f162e18   4 weeks ago   586MB
 [root@docker ~]# docker run -it --name mysql0 mysql:latest /bin/bash
 bash-5.1# ls
 afs  boot  docker-entrypoint-initdb.d  home  lib64  mnt  proc  run   srv  tmp  var
 bin  dev   etc                 lib   media  opt  root  sbin  sys  usr
 bash-5.1# find / -name "*mysql*"
 [root@docker ~]# docker rm mysql0
 mysql0
 [root@docker ~]# docker run -d --name m0 -e MYSQL_ROOT_PASSWORD=root -p3306:3306 mysql:latest 
 f8e0ec5a3db524e7c357ffdb52298185f312538fc408633191b99b412c41e6de
 # -e MYSQL_ROOT_PASSWORD=root:设置环境变量,指定 MySQL 的 root 用户密码为 “root”
 [root@docker ~]# docker ps
 CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                                                  NAMES
 f8e0ec5a3db5   mysql:latest   "docker-entrypoint.s…"   23 seconds ago   Up 21 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   m0
 # “docker-entrypoint.s…” 是容器启动时执行的命令,通常是由镜像定义的入口点脚本
 [root@docker ~]# docker exec -it m0 mysql -uroot -proot
 mysql> 
 # 外部环境测试,连接数据库,并将数据导入数据库中

复制代码
 mysql> show databases;
 +---------------------+
 | Database            |
 +---------------------+
 | information_schema  |
 | mysql               |
 | performance_schema  |
 | project_exam_system |
 | sys                 |
 +---------------------+
 5 rows in set (0.12 sec)
 mysql> use project_exam_system;
 Database changed
 mysql> show tables;
 +-------------------------------+
 | Tables_in_project_exam_system |
 +-------------------------------+
 | admin                         |
 | category                      |
 | com_city                      |
 | com_nation                    |
 | course                        |
 | dept                          |
 | dept_student                  |
 | exam                          |
 | exam_dept                     |
 | exam_process                  |
 | loginlog                      |
 | major                         |
 | menu                          |
 | paper                         |
 | paper_topic                   |
 | role                          |
 | role_admin                    |
 | role_menu                     |
 | semester                      |
 | student                       |
 | teacher                       |
 | topic                         |
 | user                          |
 +-------------------------------+
 23 rows in set (0.00 sec)
 mysql> select * from user;
 +-----+--------------+----------+--------+---------------------+----------+---------------------+--------+-------+
 | id  | userName     | password | status | createTime          | createOr | editTime            | editOr | isDel |
 +-----+--------------+----------+--------+---------------------+----------+---------------------+--------+-------+
 |   1 | 21001189     | 111111   |      0 | 2024-08-21 09:45:05 | NULL     | 2024-08-22 22:04:44 | NULL   |     0 |
 |   2 | 21001190     | 111111   |      0 | 2024-08-21 09:45:05 | NULL     | 2024-08-21 09:45:05 | NULL   |     0 |
 |   3 | 21001191     | 111111   |      0 | 2024-08-21 09:45:05 | NULL     | 2024-08-21 09:45:05 | NULL   |     0 |
 |   4 | 21001192     | 111111   |      0 | 2024-08-21 09:45:05 | NULL     | 2024-08-21 09:45:05 | NULL   |     0 |

2、让容器共享宿主的/etc/localtime(核对时间)

复制代码
 [root@docker ~]# docker run -it --name c0 centos:latest /bin/bash
 # 发现时间不对
 [root@2e86b6787031 /]# date
 Mon Aug 26 06:37:10 UTC 2024
 [root@2e86b6787031 /]# [root@docker ~]# 
 # 进行卷映射,让容器共享宿主的/etc/localtime目录
 [root@docker ~]# docker run -it --name c2 -v /etc/localtime:/etc/localtime centos:latest /bin/bash
 [root@50f5e311f6fd /]# date
 Mon Aug 26 14:39:59 CST 2024

3、为容器设置域名(容器之间的依赖link)

docker容器的ip地址是不固定的,如果要作为服务器使用,就必须能够直接访问服务,不能直接使用ip。

解决方法一:为容器设置域名

解决方法二:做端口映射也能保证,确定一旦停用之后端口被占用,就无法再次启动了

docker run --link 容器的名称或者是id:自定义域名

被link容器必须处于运行状态,该容器才能运行

复制代码
 [root@docker ~]# docker rm m0
 [root@docker ~]# docker ps
 CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
 50f5e311f6fd   centos:latest   "/bin/bash"   21 minutes ago   Up 21 minutes             c2
 2e86b6787031   centos:latest   "/bin/bash"   24 minutes ago   Up 24 minutes             c0
 [root@docker ~]# docker inspect c0
 "IPAddress": "172.17.0.3",
 [root@docker ~]# docker inspect c2
 "IPAddress": "172.17.0.4",
 [root@docker ~]# docker restart c0 c2
 [root@docker ~]# docker inspect c0
 "IPAddress": "172.17.0.2",
 [root@docker ~]# docker inspect c2
 "IPAddress": "172.17.0.3",
 # 由此发现ip地址是不固定的
 [root@docker ~]# docker rm -f c0 c2
 c0
 c2
 [root@docker ~]# docker run -d --name m0 -e MYSQL_ROOT_PASSWORD=root mysql:latest 
 d31816fbbdffb562a2539899b0ea88935549da898e075b1934a42a3b20269b98
 [root@docker ~]# docker inspect m0
 "IPAddress": "172.17.0.2",
 # 创建容器时直接指定其他容器的域名
 [root@docker ~]# docker run -it --name c0 --link m0:mysqldb centos:latest /bin/bash
 [root@b1ba0279b211 /]# ping mysqldb
 PING mysqldb (172.17.0.2) 56(84) bytes of data.
 64 bytes from mysqldb (172.17.0.2): icmp_seq=1 ttl=64 time=0.155 ms
 64 bytes from mysqldb (172.17.0.2): icmp_seq=2 ttl=64 time=0.097 ms
 [root@b1ba0279b211 /]# cat /etc/hosts
 127.0.0.1   localhost
 172.17.0.2  mysqldb d31816fbbdff m0
 172.17.0.3  b1ba0279b211
 [root@b1ba0279b211 /]# [root@docker ~]# 
 [root@docker ~]# docker ps -a
 CONTAINER ID   IMAGE           COMMAND                   CREATED         STATUS         PORTS                 NAMES
 b1ba0279b211   centos:latest   "/bin/bash"               2 minutes ago   Up 2 minutes                         c0
 d31816fbbdff   mysql:latest    "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes   3306/tcp, 33060/tcp   m0
 [root@docker ~]# docker stop m0
 m0
 [root@docker ~]# docker run -it --name c1 centos:latest /bin/bash
 [root@df7e0ae8f85e /]# [root@docker ~]# 
 [root@docker ~]# docker inspect c1
 "IPAddress": "172.17.0.2",
 [root@docker ~]# docker start m0
 m0
 # m0的ip地址已经变化
 [root@docker ~]# docker inspect m0
 "IPAddress": "172.17.0.4",
 [root@docker ~]# docker attach c0
 [root@b1ba0279b211 /]# ping m0
 PING mysqldb (172.17.0.4) 56(84) bytes of data.
 64 bytes from mysqldb (172.17.0.4): icmp_seq=1 ttl=64 time=0.109 ms
 64 bytes from mysqldb (172.17.0.4): icmp_seq=2 ttl=64 time=0.091 ms
 ^C
 --- mysqldb ping statistics ---
 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
 rtt min/avg/max/mdev = 0.091/0.100/0.109/0.009 ms
 # 发现容器里m0的对应ip地址也发生了改变
 [root@b1ba0279b211 /]# cat /etc/hosts
 172.17.0.4  mysqldb d31816fbbdff m0
 172.17.0.3  b1ba0279b211
 [root@b1ba0279b211 /]# read escape sequence
 [root@docker ~]# docker stop c0 m0
 c0
 m0
 # 没有打开m0前c0不能运行
 [root@docker ~]# docker start c0
 Error response from daemon: Cannot link to a non running container: /m0 AS /c0/mysqldb
 Error: failed to start containers: c0
 [root@docker ~]# docker start m0
 m0
 [root@docker ~]# docker start c0
 c0

4、文件联合系统overlay

1、docker client向dcoker daemon 发送创建容器的请求 docker run

2、docker daemon查找有⽆客户端需要的镜像

3、如果没有,就到容器的镜像仓库下载需要的镜像 pull

4、 拿到容器镜像后,启动容器

复制代码
 [root@docker ~]# systemctl stop docker
 Warning: Stopping docker.service, but it can still be activated by:
   docker.socket
 [root@docker ~]# cd /var/lib/docker/
 [root@docker docker]# ls
 buildkit    engine-id  network   plugins   swarm  volumes
 containers  image      overlay2  runtimes  tmp
 [root@docker docker]# cd overlay2/
 [root@docker overlay2]# ls
 0002ede20f6fc6eec6c8396ea036e47f52094a32712432b86c53184726c3ad67
 0002ede20f6fc6eec6c8396ea036e47f52094a32712432b86c53184726c3ad67-init
 008dac4bd68db493d83ddeca57f5c08a614700b6c6edd1dd4d891d8b152b0ed8
 0d0a0cc4ab149c7ef3f5744596ed7c948cde8ca5a6726e61b0fc26c97e510edb
 ......
 [root@docker overlay2]# cd 
 [root@docker ~]# rm -rf /var/lib/docker/
 [root@docker ~]# systemctl start docker
 # 在docker daemon初始状态(没有镜像的时候)/var/lib/docker是不存在的
 # 当docker daemon服务器启动,会自动创建docker目录
 [root@docker ~]# ls /var/lib/docker/
 buildkit    engine-id  network   plugins   swarm  volumes
 containers  image      overlay2  runtimes  tmp
 [root@docker ~]# docker images
 REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
 [root@docker ~]# docker ps -a
 CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
 # 在没有镜像的情况下,查看overlay2这个目录只有两个文件,管道文件,l目录(管理镜像和容器的软连接的目录)
 [root@docker ~]# ls /var/lib/docker/overlay2/
 backingFsBlockDev  l
 [root@docker ~]# docker pull centos
 [root@docker ~]# docker images
 REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
 centos       latest    5d0da3dc9764   2 years ago   231MB
 # 当我们pull一个镜像之后/var/lib/docker/overlay2下就有一个新的目录,这个目录就是centos的基础目录,这个新的目录就是镜像,就是不可读的层
 [root@docker ~]# ls /var/lib/docker/overlay2/
 b5e4ecb8bf7b53b3e8d2b3a12d61749c09b81acf384269fef6567a8d64eb61aa  backingFsBlockDev  l
 [root@docker ~]# ls /var/lib/docker/overlay2/b5e4ecb8bf7b53b3e8d2b3a12d61749c09b81acf384269fef6567a8d64eb61aa/
 diff  link
 [root@docker ~]# ls /var/lib/docker/overlay2/b5e4ecb8bf7b53b3e8d2b3a12d61749c09b81acf384269fef6567a8d64eb61aa/diff/
 bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
 dev  home  lib64  media       opt  root  sbin  sys  usr
 [root@docker ~]# docker run -it --name c0 centos:latest /bin/bash
 [root@b28ca7fa2976 /]# [root@docker ~]# 
 # 当我们使用镜像创建一个容器,在overlay2会添加两个目录,一个是init目录,另外一个目录就是容器的可写层,用户对系统的修改都在可写层
 [root@docker ~]# ls /var/lib/docker/overlay2/
 5669c778f7233fe870de858bf2f0ff78f612acca68cb9d1bd03959418c4e17c6       backingFsBlockDev
 5669c778f7233fe870de858bf2f0ff78f612acca68cb9d1bd03959418c4e17c6-init  l
 b5e4ecb8bf7b53b3e8d2b3a12d61749c09b81acf384269fef6567a8d64eb61aa
 [root@docker ~]# ls /var/lib/docker/overlay2/5669c778f7233fe870de858bf2f0ff78f612acca68cb9d1bd03959418c4e17c6
 diff  link  lower  merged  work
 # diff通常存放着容器文件系统与基础镜像相比发生变化的文件内容。当容器对文件进行修改、新增或删除操作时,这些变化会存储在这个目录中
 # link可能包含一些符号链接相关的信息,用于连接不同的层或文件系统结构
 # lower一般会列出该层所依赖的底层镜像层的标识符。Docker 的 overlay2 文件系统通过堆叠多个层来构建容器的文件系统,这个目录可以帮助确定当前层的基础层
 # merged代表容器运行时所呈现的合并后的文件系统视图。这是容器实际看到的文件系统,包含了从基础镜像层到当前容器层的所有文件和目录的合并结果
 # work可能用于存储一些临时文件或在文件系统操作过程中的中间状态数据。它在容器运行过程中可能会被动态更新
 [root@docker ~]# docker exec c0 dd if=/dev/zero of=/li.txt bs=10M count=100
 100+0 records in
 100+0 records out
 1048576000 bytes (1.0 GB, 1000 MiB) copied, 1.48925 s, 704 MB/s
 [root@docker ~]# ls /var/lib/docker/overlay2/5669c778f7233fe870de858bf2f0ff78f612acca68cb9d1bd03959418c4e17c6/merged/
 bin  etc   lib    li.txt      media  opt   root  sbin  sys  usr
 dev  home  lib64  lost+found  mnt    proc  run   srv   tmp  var

5、做一个基础镜像

proc目录是进程⽬录,sys⽬录是内核⽂件保存位置,不允许修改

复制代码
 # 排除以上2个⽬录,并且将⽤户设置为数字
 [root@localhost ~]# tar --numeric-owner --exclude=/proc --exclude=/sys -cvf li.tar /
 # 将项⽬移动到dockerserver主机上
 [root@localhost ~]# scp li.tar 10.0.0.100:~
 # 加载镜像
 [root@docker ~]# docker import -m "tar" centos7.tar tar:tar
 ​

6、使用commit命令直接将容器封装为镜像

bash 复制代码
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
centos       latest    5d0da3dc9764   2 years ago   231MB
[root@docker ~]# ls /var/lib/docker/overlay2/
1b35ad7d06fca0875e8b0a3435a388a514f509bd89857786818953cc96b9b319  backingFsBlockDev  l
[root@docker ~]# docker run -it --name c0 centos:latest /bin/bash
[root@7b202e1e4d88 /]# rm -rf /etc/yum.repos.d/*
[root@7b202e1e4d88 /]# ls /etc/yum.repos.d/
[root@7b202e1e4d88 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
[root@7b202e1e4d88 /]# yum clean all && yum makecache
[root@7b202e1e4d88 /]# yum -y install nginx
[root@7b202e1e4d88 /]# echo "hh" > /usr/share/nginx/html/index.html 
[root@7b202e1e4d88 /]# [root@docker ~]# 
[root@docker ~]# docker --help
 commit      Create a new image from a container changes
[root@docker ~]# docker commit c0 centos:nginx
sha256:829a639e0772069c9c25e3f2a903599f41512643244b7dcd93a9b367ea2f00e8
[root@docker ~]# docker images
centos         nginx     12fea1b890de   24 hours ago     366MB
[root@docker ~]# ls /var/lib/docker/overlay2/
1b35ad7d06fca0875e8b0a3435a388a514f509bd89857786818953cc96b9b319
454fae2c1202c423b82f053bed8d209704794f33f181afdc1a0ef30e919c0137
a82ba8d9faba825e81f903515607b66436ef823fd9e5fe606ee684784e034f36
a82ba8d9faba825e81f903515607b66436ef823fd9e5fe606ee684784e034f36-init
backingFsBlockDev
l
[root@docker ~]# ls /var/lib/docker/overlay2/a82ba8d9faba825e81f903515607b66436ef823fd9e5fe606ee684784e034f36/diff/
etc  tmp  usr  var
[root@docker ~]# ls /var/lib/docker/overlay2/a82ba8d9faba825e81f903515607b66436ef823fd9e5fe606ee684784e034f36/diff/etc/yum.repos.d/
CentOS-Base.repo                     CentOS-Linux-FastTrack.repo
CentOS-Linux-AppStream.repo          CentOS-Linux-HighAvailability.repo
CentOS-Linux-BaseOS.repo             CentOS-Linux-Media.repo
CentOS-Linux-ContinuousRelease.repo  CentOS-Linux-Plus.repo
CentOS-Linux-Debuginfo.repo          CentOS-Linux-PowerTools.repo
CentOS-Linux-Devel.repo              CentOS-Linux-Sources.repo
CentOS-Linux-Extras.repo
[root@docker ~]# ls /var/lib/docker/overlay2/a82ba8d9faba825e81f903515607b66436ef823fd9e5fe606ee684784e034f36/diff/var/
cache  lib  log  tmp
[root@docker ~]# docker rm -f c0
c0
[root@docker ~]# ls /var/lib/docker/overlay2/
1b35ad7d06fca0875e8b0a3435a388a514f509bd89857786818953cc96b9b319  backingFsBlockDev
454fae2c1202c423b82f053bed8d209704794f33f181afdc1a0ef30e919c0137  l
[root@docker ~]# docker run -it --name c0 centos:nginx /bin/bash
[root@c733fe6612a3 /]# nginx
[root@c733fe6612a3 /]# curl localhost
hh
相关推荐
CodeCaptain几秒前
Dify结合vllm-openai docker镜像出现docker: invalid reference format问题的解决方案
运维·docker·容器
Awkwardx6 分钟前
MySQL数据库—MySQL复合查询
数据库·mysql
LucidX7 分钟前
Kubernetes Pod 详解与Rancher 部署
容器·kubernetes·rancher
星环处相逢9 分钟前
从 Pod 核心原理到 Rancher 实战:K8s 容器管理全解析
容器·kubernetes·rancher
伞啊伞12 分钟前
k8s(四) Rancher 管理集群
容器·kubernetes·rancher
忍冬行者13 分钟前
k8s的etcd的一键备份和故障恢复
docker·云原生·容器·kubernetes·云计算
QWsin17 分钟前
【k8s】为什么statefulSet初始化pod需要service name
云原生·容器·kubernetes
lin张17 分钟前
k8s(三)pod详解(精简版)
云原生·容器·kubernetes
亮子AI20 分钟前
【MySQL】node.js 如何批量更新数据?
数据库·mysql·node.js
小二·21 分钟前
前端 DevOps 完全指南:从 Docker 容器化到 GitHub Actions 自动化部署(Vue 3 + Vite)
前端·docker·devops