Docker 快速入门实操教程(完结)

Docker 快速入门实操教程(完结)

Docker,启动!

如果安装好Docker不知道怎么使用,不理解各个名词的概念,不太了解各个功能的用途,这篇文章应该会对你有帮助。

前置条件:已经安装Docker并且Docker成功启动。

实操内容:使用Docker容器替换本地安装的程序并迁移数据(MySQLredis)。

最终目的:熟练使用Docker各项功能。

理解概念

Docker官方提供了一个分发平台DockerHub,可以从上面拉取已经提供好的镜像直接构建容器运行。

这个过程会涉及到Docker的一些概念,在刚接触的时候比较抽象,这里以烘焙出一个蛋糕为例子说明一下:

  • Dockerfile 蛋糕的配方。配方上详细列出了需要的材料(如面粉、糖、鸡蛋)以及烘焙的步骤(如先将面粉和糖混合,然后加入鸡蛋搅拌)。
  • 镜像(Image): 按照配方做出了一个半成品蛋糕,这就是蛋糕的"镜像" 。这个蛋糕可以被任何人复制,每一个复制品都会和原蛋糕一模一样。
  • 容器(Container): 将半成品蛋糕烘焙后,得到一个可食用的蛋糕。可以根据同一个镜像制作出很多个完全一样的蛋糕,也可以在烘焙时自己加一些材料。每个蛋糕都是独立的,和其他蛋糕没有关联。

所以从DockerHub拉取镜像并且跑起来的过程就可以理解为:

  1. 镜像提供者编写好了配方( Dockerfile ),将其制成( 构建 )了半成品蛋糕( 镜像 )。
  2. 用户购买( 拉取 )这个半成品蛋糕。
  3. 烘焙( 创建 )后得到了一个可食用的蛋糕( 容器 ),食用蛋糕( 运行容器 )。
  4. 通常创建容器和运行容器都会归拢在同一步:创建并运行。

还有另外两个比较重要的概念: 层(Layers缓存(Cache ,目前不会接触到,可以在看 构建/推送镜像 这一节时再去深入理解。

创建/运行容器

每一步都提供了Docker desktop(简称桌面版)的操作截图和终端命令(桌面版界面友好但局限较大,仅适合初步上手)。

拉取镜像

DockerHub拉取MySQL镜像到本地,这一步可能会因为网络原因失败,可以配置其他镜像源或者使用代理,网上教程很多。

image-20240128210738711

终端命令

docker pull 仓库地址/命名空间/镜像名称:标签
  • 仓库地址: 没有显式指定仓库地址时,默认会从DockerHub查找镜像;拉取私有仓库的镜像,需要指定仓库地址。
  • 命名空间: 截图最后有一个名为 ubuntu/mysql 的镜像,其中 ubuntu 是命名空间,用以区分不同的个人或组织发布的镜像。没有显式指定命名空间时,默认会查找官方团队发布的镜像。
  • 镜像名称: 需要拉取的镜像的名称。
  • 标签: 没有显式指定标签时,默认会拉取 latest 标签, latest 表示这是最新的版本。

通过 docker pull 拉取镜像并不是必须的,在 docker run 时,如果本地不存在指定镜像,Docker会自动拉取。

创建并运行容器

拉取完成后,通过 docker run 创建容器并运行前进行一些配置:

image-20240128213738553

终端命令

# 截图对应命令
docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:latest# 完整命令
docker run [选项参数] 仓库地址/命名空间/镜像名称:标签 [命令行] [命令行参数]
  • 选项参数:

    --name :设置容器名称,不能重复,这里使用的是 镜像名_版本号 的方式。

    -p :设置端口映射,将宿主机的 3306 端口映射到容器的 3306 端口,宿主机上的其他进程通过该端口才能访问到容器内的服务。如果不配置端口映射,则只能在容器内部访问服务或通过虚拟网络让容器可以相互通信。

    -e :设置环境变量,配置 MYSQL_ROOT_PASSWORD=root 用以指定root用户密码,这是由镜像创建者约定的,不同的镜像配置项会有所不同。

    -v :设置目录挂载,用法参考 目录挂载 章节。

    -d :让容器在后台运行

  • 命令行: 在容器启动时执行命令(如 ls ),可以省略。

  • 命令行参数: 传给 命令行 的额外参数(如 /etc ,这样在容器启动时就会执行 ls /etc ),可以省略。

常用命令

容器已经创建好后就不再适用于 docker run 命令了, docker run 命令主要是用于创建新的容器并运行,如果需要启动已经存在的容器,则使用 docker start 命令。

# 列出所有容器
docker ps -a# 列出所有镜像
docker image ls
docker images# 启动容器
docker start 容器名称/容器ID# 停止容器
docker stop 容器名称/容器ID# 强制停止容器
docker kill 容器名称/容器ID# 重启容器
docker restart 容器名称/容器ID# 删除容器
docker rm 容器名称/容器ID# 删除镜像
docker rmi 容器名称/容器ID

目录挂载

现存问题:

  • 数据没有保存到宿主机中,当容器删除后,数据就丢失了。
  • 宿主机和容器之间的文件传递比较麻烦。
  • 多个容器需要共享数据。

目录挂载可以解决以上问题,Docker为目录挂载提供了三种方式:

  • bind mount: 把宿主机目录映射到容器内,双向文件传递。适合变动比较频繁的场景,比如代码目录、配置文件等。

  • volume: 由容器创建和管理,存储在宿主机中,官方推荐,Linux 文件系统。适合存储不需要关心的数据,如数据库数据。

  • tmpfs mount: 适合存储临时文件,存储在宿主机内存中。不可多容器共享。

以MySQL镜像为例,其 Dockerfile 中写了创建 volume 用于持久化保存数据的命令(其他镜像也可以通过这种方式查看需要持久化的目录)。

image-20240128224015528

虽然 Dockerfile 中有创建 volume 的命令,但是如果创建容器时没有主动为 volume 命名,其就是匿名 volume Docker会为匿名 volume 随机生成一个名称,当挂载该 volume 的容器被删除后,该 volume 也会被删除。

当创建容器时主动指定的 volume 路径和 Dockerfile 约定的路径一致,则该镜像创建的 volume 就不会被挂载为匿名 volume 了,容器删除后该 volume 也会保留,这也是最方便的一种命名方式。

image-20240128220629652

终端命令

docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v=mysql_volume:/var/lib/mysql -v D:\mount:/pc_mount mysql:latest

挂载目录时,如果只赋予了名称则是 volume 方式,如果指定了具体目录就是 bind mount 方式。

所以在这个容器中:

  1. 将容器内的 /var/lib/mysql 目录挂载为 volume 并且命名为 mysql_volume
  2. 将宿主机的 D:\mount目录映射至容器中的 /pc_mount

在挂载目录时,如果你指定的目录不存在于容器中,则会自动创建,这里的 /pc_mount 目录就会自动被创建。

迁移实操

现在需要将宿主机中MySQL数据迁移到容器中,打算采用navicat的数据迁移工具,那么就需要同时运行两个数据库,端口同为 3306 会冲突,宿主机上MySQL端口改起来并不方便,容器创建后端口也不能修改,那么就可以使用数据挂载的方式。

迁移方案:

  1. 停止运行端口为 3306 MySQL容器。
  2. 新创建一个MySQL容器,端口指定为 3305 (或其他任意未被占用的端口),指定 volume 的名称和端口 3306 的容器一致。
  3. 迁移数据,删除端口为 3305 的容器,运行端口为 3306 的容器,数据迁移成功。

当数据库文件较大时,使用navicat迁移则会显得有些性能不足了,这时候就需要通过命令行导入:

  1. 将需要导入的SQL文件放在宿主机挂载的目录下(宿主机: D:\mount ;容器: /pc_mount )。

  2. 打开容器的终端

    docker exec -it mysql_8.3.0 bash
    

  3. 登入MySQL并选择需要导入的数据库

    mysql -u root -proot
    use test-base;
    source /pc_mount/001.sql;
    

从容器中导出SQL文件到宿主机同理,将SQL文件导出至挂载的 /pc_mount 目录下,在宿主机的 D:\mount 就可以看到。

虚拟网络

每个Docker容器都运行在自己的环境中,互不干扰,所以上述内容中都依赖宿主机的端口映射进行容器通信。但是有些时候我们只要让这个项目能在宿主机上访问到,并不在意其所依赖的服务是否能够被宿主机操作和管理。就可以通过Docker提供的虚拟网络实现容器之间的通信,再映射项目入口到宿主机即可。

桌面版并没有为虚拟网络提供较好的GUI支持,需要终端执行。

# 查看已存在的虚拟网络
docker network ls

默认已经存在了三个虚拟网络,这是由Docker创建的,对应着不同的网络驱动类型,驱动类型的区别如下:

  • Bridge网络: 默认值。容器在独立的网络空间运行,可以相互通信并访问外部网络。容器内服务能通过端口映射被外部访问。
  • Host网络: 容器共享宿主机的网络空间,不再需要端口映射,直接使用宿主机的端口。这种模式提供了最高的网络性能,但是失去了隔离性。
  • None网络: 容器拥有自己的网络空间,但不配置任何网络接口。它只有本地回环接口,没有任何外部网络访问能力,提供了最高的网络隔离性。
# 创建名为 test_net 的网络
docker network create test_net# 在该网络下创建两个容器
docker run --name redis_temp --network=test_net -d redis:latest
docker run --name redisinsight -p 8001:8001 --network test_net -d redislabs/redisinsight:latest

创建了redis容器,但是并没有为其映射端口。所以现在在宿主机中并不能访问到这个redis容器。

创建了redisInsight容器并且映射了8001端口,这是一个redisGUI工具,用于测试是否可以通过虚拟网络访问到redis容器。

访问 http://localhost:8001/ 进入redisInsight的主页,添加一个redis数据库。

Docker内部的DNS服务会自动将容器名称解析为容器对应的IP地址(即容器名称就是域名),所以主机地址填写容器名称即可。

image-20240129172212539

连接成功,这样既可以操作容器内的redis数据,又不会占用宿主机自身的redis应用抢占端口。同理,部署其他项目时,如果项目容器需要连接数据库容器,也可以通过虚拟网络实现。

如果容器已经被创建,可以更改已存在的容器的连接的网络

docker network connect 网络名称 容器名称

使用技巧

查看软件版本

部分镜像的 Tag latest ,并没有明确指出具体的版本号,想要查看版本号就只能手动查看。

桌面版点击容器右侧 ··· 打开更多选项,选择 Open in terminal 进入容器的终端,执行该软件查看版本的命令。

终端命令

docker exec mysql_8.3.0 mysql -V

但是问题就来了,如果需要版本号是为了给容器命名,这种方案需要先运行容器,将容器删除,再重新创建容器,很麻烦。

通常镜像的环境变量中会指明版本号,可以直接点开镜像查看

image-20240128220336815

终端命令

docker inspect mysql:latest

这个方式虽然比较方便,但是需要进行推测,并非一定正确。

保持容器运行

当在桌面版运行ubuntu等容器时,会发现容器启动后就停止了,进入 Exited 状态,如果想要容器持续运行,就需要需要在容器内部执行一个持续运行的进程。

桌面版已经不能满足需求了,需要终端执行

docker run -it --name ubuntu_22.04 ubuntu:latest

-t 指令分配一个虚拟的终端或控制台,可以让容器持续运行不会关闭。

-i 指令可以让打开的控制台能够接受用户输入。

构建/推送镜像

想要通过Docker将项目部署到服务器上或是分发项目供他人使用,就需要将项目构建为镜像,官方主要推荐通过 Dockerfile 构建镜像。 Dockerfile 是一个文本文件(无文件后缀),由一系列的命令和参数构成,这些命令对应了在构建镜像时的操作步骤。

编写Dockerfile文件

Dockerfile常用指令:

  • FROM: 指定基础镜像。所有后续的操作都是基于这个基础镜像进行的。
  • WORKDIR: 设定后续命令的执行目录。
  • COPY: 复制文件、指定目录中的所有内容(不含目录本身)到镜像中。
  • ADD: 复制文件、指定目录中的所有内容(不含目录本身)到镜像中。对tar格式的压缩文件会自动解压。
  • RUN: 构建过程中执行命令。比如安装一些软件,创建一些文件等。
  • CMD: 为容器提供默认的执行命令,会被 docker run 的命令行参数覆盖。
  • ENTRYPOINT: 为容器提供默认的执行命令,不会被 docker run 的命令行参数覆盖。
  • EXPOSE: 公开容器的一个端口供外部访问。

通过maven执行 package 手动将项目打包,命名为 output-dem.jar ,在项目根目录下新建一个 Dockerfile 文件:

# 使用JDK17基础镜像
FROM openjdk:17-jdk-slim# 设置工作目录,容器也会使用该目录作为工作目录
WORKDIR /app# 将jar包复制到/app路径下
COPY target/output-demo.jar app.jar# 设置在运行此镜像后默认执行的命令,让它运行刚才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]# 暴露端口,取决于项目实际使用的端口号
EXPOSE 8080

如果不是Java开发,设备上并没有安装 JDK maven 等构建需要的环境(其他语言同理),但是又有打包项目的需求,则可以通过多阶段构建的方式,在镜像中完成编译等操作:

# 使用包含JDK17和Maven3.8.5的基础镜像
# 将本构建阶段命名为 build ,以便在后面的阶段中引用
FROM maven:3.8.5-openjdk-17-slim AS build# 设置工作目录,容器也会使用该目录作为工作目录
WORKDIR /app# 将当前目录下的所有文件添加到工作目录下(.和./都可以表示当前目录)
ADD . .# 使用Maven构建项目为jar包
RUN mvn clean package
# 使用Maven构建项目为jar包(跳过测试阶段)
# RUN mvn clean package -DskipTests=true# 新的构建阶段
# 引入JDK17的基础镜像
FROM openjdk:17-jdk-slim# 设置工作目录,容器也会使用该目录作为工作目录
WORKDIR /app# 将 build 阶段构建jar包复制到新阶段的/app路径下
COPY --from=build /app/target/output-demo.jar app.jar# 设置在运行此镜像后默认执行的命令,让它运行刚才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]# 暴露端口,取决于项目实际使用的端口号
EXPOSE 8080

Docker的多阶段构建中,每次使用新的 FROM 指令,都会开始一个新的构建阶段,上一阶段的指令会创建为一个临时的镜像。在新阶段中,前一阶段的层和设置都被丢弃,只有 --from 指定的之前阶段的内容被保留,就像是开始了一个全新的 Dockerfile 一样。

构建镜像

写好 Dockerfile 后,就可以通过该文件构建镜像了

 docker build -t 仓库地址/命名空间/镜像名:标签 .docker build -t 仓库地址/命名空间/镜像名:标签 -f /path/myDockerfile .

-t 指定镜像名称(如果不推送到私有仓库,仅本地使用, 仓库地址/命名空间/ 可以省略)。

-f 指定 Dockerfile 所在的目录,也可以指定 自定义名称的Dockerfile -f 参数可省略)。

. 使用当前目录下作为上下文环境, COPY 等命令会从该目录查找文件。未指定 -f 参数时,则使用上下文环境中名为 Dockerfile 的文件。

推送镜像

每次发布更改内容都需要打包镜像后上传到生产环境再部署很麻烦,将镜像推送至私有仓库中,在生产环境直接从仓库中拉取镜像则更加高效。

# 登录仓库
docker login 仓库地址# 推送镜像
docker push 仓库地址/命名空间/镜像名:标签

没有显式指定仓库地址时,默认会将DockerHub作为仓库地址。

层与缓存

层(Layers): 根据 Dockerfile 构建镜像时,每一个会改变文件系统状态的指令( RUNCOPY ADD 等)都会新建一个层 ,每个层都是前一层的改动的结果,并且每个层都只保留改动的部分,共享未改动的部分。依次将所有的层合并起来就是完成的镜像。

根据这个例子可以方便理解层的概念:

# Dockerfile A
RUN apt-get install -y software-package # 第一层
RUN rm -rf /var/lib/apt/lists/* # 第二层

在这个片段中,第一层中安装了一个软件包,第二层中删除了软件包。

因为 每个层都是前一层的改动的结果 ,所以第二层的删除文件并不能影响到第一层,只是会在第二层中对该文件打上一个 删除 的标记,这个文件会作为一个无用的文件存在于最终构建的镜像中,增加了镜像的体积。

# Dockerfile B
RUN apt-get install -y software-package && rm -rf /var/lib/apt/lists/*

在这个片段中,安装和删除软件包是在同一个指令下执行的,所以他们是处于同一层的操作,当这一层的构建结束时,这些文件就会被清理掉,它们也就不会存在于最终的镜像中了。


缓存: 缓存多个镜像之间可以共享层,如果多镜像都是基于同一个基础镜像进行构建的。那么,这个基础镜像的所有层都只需要存储一次,就能在所有的镜像中共享。如果一个镜像的大部分层已经在本地存在,那么在拉取这个镜像时,只有不存在的层需要被下载,这可以极大地节省时间和网络带宽。

Docker Compose

当项目依赖的服务较多时,每个容器都要单独配置运行,指定网络。使用Docker Compose,可以通过一个YAML文件定义服务,并同时运行它们。

Docker Compose将所管理的容器分为三层:工程(Project)、服务(Service)、容器(Container)。

通过一个例子来理解三层结构:

  1. 工程: 一个工程可以被视为一家公司,它为所有服务提供了整体的工作环境和资源配置。
  2. 服务: 公司内设有各种部门,如财务和行政等,每个部门有自己特定的职责和任务。每个部门都可以被看作一个服务。
  3. 容器: 每个部门由一个或多个员工组成。尽管每个员工都是独立的,但他们共享同样的环境。一个员工相当于一个容器。

所有部门都在同一家公司工作并使用该公司的资源,所以所有服务在工程中共享同样的网络、卷等资源

各个部门之间还是会进行交流和协作,所以各个服务之间可以互相通信

同一部门的所有员工都具有相同的工作环境,所以属于同一服务的所有容器都有统一的配置。员工各自做自己的项目,所以容器间有一定的隔离性

在要部署项目的目录创建一个 docker-compose.yml 文件:

# 指定Docker Compose配置文件的版本
version: '3.8'services: # 定义应用服务,名为 appapp:image: '仓库地址/命名空间/镜像名称:标签'# 将容器的8080端口映射到宿主机的8080端口ports: - 8080:8080 volumes:# 将 docker-compose.yml 所在目录映射到容器中的 /app 目录(在 Dockerfile 中给定的工作目录) - ./:/app # 定义启动依赖,会先启动 mysqldb 和 redisdb,再启动 appdepends_on:- mysqldb- redisdb# 指定容器启动后执行的命令command: ["java", "-jar", "app.jar"]   # 如果服务非手动停止,Docker会自动尝试重启服务restart: always# 定义一个MySQL服务,名为 mysqldb # 其他服务连接MySQL数据库时,主机地址就是 mysqldb:3306mysqldb:image: mysql:8.0.30environment:- MYSQL_ROOT_PASSWORD=rootvolumes:- db_data:/var/lib/mysql# 定义一个Redis服务,名为 redisdb# 其他服务连接Redis数据库时,主机地址就是 redisdb:6379redisdb:image: redis:7.2.4volumes:- redis_data:/datavolumes:db_data:redis_data:

docker-compose.yml 文件所在的目录执行

docker compose up -d

docker compose up 根据 docker-compose.yml 文件内容启动、创建、连接服务。

-d 参数表示以后台方式运行。

-f 如果文件名称不是 docker-compose.yml ,可以通过 -f 命令指定,使用方法与 构建镜像 章节一致。

每次更改了 docker-compose.yml 文件,都需要重新运行 docker-compose up -d 命令以应用更改。

结语

任何技术都有其深度与复杂性,难以通过一篇文章详尽阐述。本文的初衷是为你在遭遇问题时,提供一个寻找解答的方向指引。

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

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

相关文章

IOS 发布遇到“Unable to authenticate with App Store Connect”错误咋解决?

问题: 在开发ios app后,先发布adhoc版本,测试通过后,再发布testflight版本测试,但是可能会遇到一下问题。 解决办法: 在Signing &Capabilities中,在ios下边要指定有发布权限的Team账号&a…

pytorch基础2-数据集与归一化

专题链接:https://blog.csdn.net/qq_33345365/category_12591348.html 本教程翻译自微软教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次编辑:2024/3/2;最后编辑:2024/3/2 本教程…

迪杰斯特拉算法的具体应用

fill与memset的区别介绍 例一 #include <iostream> #include <algorithm> using namespace std; const int maxn500; const int INF1000000000; bool isin[maxn]{false}; int G[maxn][maxn]; int path[maxn],rescue[maxn],num[maxn]; int weight[maxn]; int cityn…

探索数据宇宙:深入解析大数据分析与管理技术

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

第六课:NIO简介

一、传统BIO的缺点 BIO属于同步阻塞行IO,在服务器的实现模型为&#xff0c;每一个连接都要对应一个线程。当客户端有连接请求的时候&#xff0c;服务器端需要启动一个新的线程与之对应处理&#xff0c;这个模型有很多缺陷。当客户端不做出进一步IO请求的时候&#xff0c;服务器…

《Spring Security 简易速速上手小册》第4章 授权与角色管理(2024 最新版)

文章目录 4.1 理解授权4.1.1 基础知识详解授权的核心授权策略方法级安全动态权限检查 4.1.2 主要案例&#xff1a;基于角色的页面访问控制案例 Demo 4.1.3 拓展案例 1&#xff1a;自定义投票策略案例 Demo测试自定义投票策略 4.1.4 拓展案例 2&#xff1a;使用方法级安全进行细…

c语言数据结构(5)——栈

欢迎来到博主的专栏——C语言数据结构 博主id&#xff1a;代码小豪 文章目录 栈栈的顺序存储结构栈的插入空栈的初始化栈的删除判断空栈读取栈顶元素数据 实现顺序栈的所有代码栈的链式存储结构链式栈的初始化链式栈的入栈操作链式栈的出栈操作 实现链式栈的所有代码 栈 栈是…

学习网络编程No.11【传输层协议之UDP】

引言&#xff1a; 北京时间&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周实现了更文两篇&#xff0c;所以这周再接再厉。当然做题任在继续&#xff0c;而目前做题给我的感觉以套路和技巧偏多&#xff0c;还是那句话很多东西不经历你就是不懂&#xff…

【Python】2. 基础语法

常量和表达式 我们可以把 Python 当成一个计算器, 来进行一些算术运算. 注意: print 是一个 Python 内置的 函数, 这个稍后详细介绍. 可以使用 - * / ( ) 等运算符进行算术运算. 先算乘除, 后算加减. 运算符和数字之间, 可以没有空格, 也可以有多个空格. 但是一般习惯上写一…

LDR6328芯片:智能家居时代的小家电充电革新者

在当今的智能家居时代&#xff0c;小家电的供电方式正变得越来越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片进行诱骗取电&#xff0c;为后端小家电提供稳定电压的技术&#xff0c;正逐渐成为行业的新宠。在这一领域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写&#xff08;32位有符号数&#xff09; 第二章&#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…

前端Vue3项目如何打包成Docker镜像运行

将前端Vue3项目打包成Docker镜像并运行包括几个主要步骤&#xff1a;项目打包、编写Dockerfile、构建镜像和运行容器。下面是一个基本的流程&#xff1a; 1. 项目打包 首先&#xff0c;确保你的Vue3项目可以正常运行和打包。在项目根目录下执行以下命令来打包你的Vue3项目&am…

nest.js使用nest-winston日志一

nest-winston文档 nest-winston - npm 参考&#xff1a;nestjs中winston日志模块使用 - 浮的blog - SegmentFault 思否 安装 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口协议】GTP-U协议介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

基础小白快速入门Python------>模块的作用和意义

模块&#xff0c; 这个词听起来是如此的高大威猛&#xff0c;以至于萌新小白见了瑟瑟发抖&#xff0c;本草履虫见了都直摇头&#xff0c;好像听上去很难的样子&#xff0c;但是但是&#xff0c;年轻人&#xff0c;请听本少年细细讲述&#xff0c;他只是看起来很难&#xff0c;实…

GO-接口

1. 接口 在Go语言中接口&#xff08;interface&#xff09;是一种类型&#xff0c;一种抽象的类型。 interface是一组method的集合&#xff0c;接口做的事情就像是定义一个协议&#xff08;规则&#xff09;&#xff0c;只要一台机器有洗衣服和甩干的功能&#xff0c;我就称它…

【go语言开发】swagger安装和使用

本文主要介绍go-swagger的安装和使用&#xff0c;首先介绍如何安装swagger&#xff0c;测试是否成功&#xff1b;然后列出常用的注释和给出使用例子&#xff1b;最后生成接口文档&#xff0c;并在浏览器上测试 文章目录 安装注释说明常用注释参考例子 文档生成格式化文档生成do…

大模型生成,Open API调用

大模型是怎么生成结果的 通俗原理 其实&#xff0c;它只是根据上文&#xff0c;猜下一个词&#xff08;的概率&#xff09;…… OpenAI 的接口名就叫【completion】&#xff0c;也证明了其只会【生成】的本质。 下面用程序演示【生成下一个字】。你可以自己修改 prompt 试试…

【C++】类的转换函数

使用场景 C中当你创建了一个类&#xff0c;你想把这个类对象转换成基本类型的函数。类对象->基本类型对象 原理 如下实例&#xff0c;设计一个分数类&#xff0c;实现分数转换成double 浮点数的转换函数。并在mian函数隐式调用。 #include<iostream> class Fractio…

Python爬虫Cookies 池的搭建

Cookies 池的搭建 很多时候&#xff0c;在爬取没有登录的情况下&#xff0c;我们也可以访问一部分页面或请求一些接口&#xff0c;因为毕竟网站本身需要做 SEO&#xff0c;不会对所有页面都设置登录限制。 但是&#xff0c;不登录直接爬取会有一些弊端&#xff0c;弊端主要有…