当前位置: 首页 > news >正文

网站建设:博采网络/长沙网红奶茶

网站建设:博采网络,长沙网红奶茶,找个建设网站的网管,网站程序设计文章目录 前言:项目部署的挑战一、初识 Docker1.1 什么是 Docker1.2 Docker 与 虚拟机的区别1.3 镜像和容器以及镜像托管平台1.4 Docker的架构解析1.5 Docker 在 CentOS 中的安装 二、Docker 的基本操作2.1 操作 Docker 镜像命令2.1.1 镜像操作相关命令2.1.2 示例一…

文章目录

  • 前言:项目部署的挑战
  • 一、初识 Docker
    • 1.1 什么是 Docker
    • 1.2 Docker 与 虚拟机的区别
    • 1.3 镜像和容器以及镜像托管平台
    • 1.4 Docker的架构解析
    • 1.5 Docker 在 CentOS 中的安装
  • 二、Docker 的基本操作
    • 2.1 操作 Docker 镜像命令
      • 2.1.1 镜像操作相关命令
      • 2.1.2 示例一:从 DockerHub 拉取一个 nginx 镜像
      • 2.1.3 示例二:使用 save 将 nginx 镜像导出磁盘,然后再通过 load 加载回来
    • 2.2 Docker 容器命令详解
      • 2.2.1 操作容器相关命令
      • 2.2.2 示例一:运行 nginx 镜像
      • 2.2.3 示例二:进行 Nginx 容器内部,修改HTML文件内容
    • 2.3 操作 Docker 数据卷命令详解
      • 2.3.1 容器与数据耦合的问题
      • 2.3.2 什么是数据卷
      • 2.3.3 数据卷相关操作命令
      • 2.3.4 示例一:创建一个数据卷,并查看数据卷在宿主机的目录位置
      • 2.3.5 示例二:创建nginx容器的同时创建数据卷,通过数据卷修改 HTML 内容
  • 三、Dockerfile 自定义镜像的创建
    • 3.1 镜像文件的结构详解
    • 3.2 Dockerfile 文件详解
    • 3.3 示例一:基于 Ubuntu 镜像构建一个新镜像,运行一个 Java 项目
    • 3.4 示例二:基于 java:8-alpine 镜像,修改示例一的 Dockerfile 文件


前言:项目部署的挑战

在部署大型项目时,常常面临多组件、复杂的依赖关系和不同环境之间的差异,这些因素可能导致以下问题:

  1. 复杂的依赖关系: 由于项目组件众多,各个组件之间的依赖关系变得复杂,容易出现版本不匹配或兼容性问题。

  2. 兼容性问题: 项目在不同的环境中可能会遇到兼容性挑战,导致在一个环境中正常运行的组件在另一个环境中出现问题。

  3. 环境差异: 开发、测试和生产环境之间存在差异,可能涉及操作系统、库版本、配置等方面的不一致性,增加了部署的复杂性。

这些挑战使得项目部署变得复杂且容易出错。为了解决这些问题,引入Docker技术是一个有效的方案。Docker的容器化特性能够提供一致的运行环境,简化依赖管理,并减轻不同环境之间的差异性,从而提高部署的可靠性和效率。在接下来的内容中,我们将深入了解Docker的基本概念以及如何利用Docker解决这些项目部署的挑战。

一、初识 Docker

1.1 什么是 Docker

Docker 是一种开源的容器化平台,旨在简化应用程序的开发、交付和部署过程。通过使用容器技术,Docker 能够将应用程序、所有依赖项以及程序运行所需要的环境打包成一个独立的容器。这个容器包含了运行应用所需的一切,包括操作系统、库和代码等等。这种打包的方式使得应用程序在任何环境中都能够以一致的方式运行,从而实现了跨平台、可移植和快速部署的优势。

Docker 是一项旨在实现快速交付应用和高效运行应用的技术。它提供了以下主要特性:

  1. 容器化打包: Docker允许将程序、其依赖以及运行环境一同打包成一个独立的镜像。这个镜像包含了应用程序所需的一切,从操作系统到所有依赖库,形成了一个可移植的、一致的运行环境。

  2. 跨平台移植性: 由于 Docker 镜像是独立的、轻量级的打包,因此可以轻松迁移到任意支持 Docker 的 Linux 操作系统,无需担心环境差异性问题。

  3. 沙箱隔离: 运行时,Docker 利用沙箱机制为每个容器创建独立的运行环境,使得各个应用程序在容器内互不干扰。这种隔离性确保了安全性和可靠性。

  4. 便捷的管理命令: Docker 提供了简单而强大的命令行工具,用户可以使用一行命令完成启动、停止、移除容器等操作。这种便捷性提高了应用程序的开发、测试和部署效率。

总体而言,Docker 为开发人员提供了一种先进的、可移植的容器化解决方案,通过将应用程序及其运行时环境打包成镜像,实现了快速部署和跨平台运行的便利性。同时,沙箱隔离机制确保了多个应用程序之间的独立性,使得Docker成为现代应用开发和部署的理想选择。

1.2 Docker 与 虚拟机的区别

Docker和虚拟机是两种常见的容器化技术,它们在实现虚拟化和隔离的方式以及性能表现上存在一些区别。在理解Docker和虚拟机之前,首先我们可以简单了解它们的层次结构:

Docker vs 虚拟机

通过上图可以发现虚拟机是使用 Hypervisor 在操作系统上模拟出计算机硬件,然后再在这个虚拟硬件上安装的操作系统;而 Docker 容器则是直接运行在操作系统上的。因此 Docker 的性能会远远优于虚拟机。

下面我们来比较一下 Docker 和虚拟机的特性:

特性Docker虚拟机
性能接近原生性能较差
硬盘占用一般为MB一般为GB
启动秒级分钟级

Docker的优势:

  1. 性能: Docker容器直接运行在宿主操作系统的内核上,因此性能接近原生,而虚拟机需要在Hypervisor的管理下运行,性能相对较差。

  2. 硬盘占用: Docker镜像是轻量级的,通常只有MB级别,而虚拟机的镜像则往往是GB级别,因此Docker在硬盘占用上更为高效。

  3. 启动速度: Docker容器启动非常迅速,可以达到秒级的启动时间,而虚拟机的启动则需要较长的时间,通常是分钟级。

总体而言,Docker适用于快速部署、轻量级应用,而虚拟机则更适合需要完全隔离的复杂应用。选择使用哪种技术取决于具体的应用场景和需求。

1.3 镜像和容器以及镜像托管平台

在Docker的世界里,镜像和容器是两个核心概念,理解它们是使用 Docker 的关键。

镜像是什么?

镜像是一个轻量级、独立的可执行软件包,包含运行应用程序所需的一切:代码、运行时、系统工具、系统库,以及设置。简单来说,镜像就是一个应用程序的打包。

构成要素:

  1. 应用程序代码: 你的应用程序的所有文件和代码。
  2. 运行时: 定义应用程序如何运行的配置文件。
  3. 系统工具: 用于操作系统和应用程序的工具。
  4. 系统库: 应用程序所需的任何库文件。

特点:

  • 不可修改性:一旦构建,镜像的内容不可更改。
  • 轻量性:镜像通常很小,因为它只包含运行应用程序所需的最小内容。

例子:

  • 一个运行Node.js应用的镜像可能包含Node.js运行时、应用代码、以及一些操作系统工具。

容器是什么?

容器是镜像的运行实例。可以将容器视为一个轻量级、独立的可执行包,包含应用程序、运行时和系统工具,并根据镜像的定义执行。

特点:

  • 隔离性:容器之间相互隔离,一个容器的变化不会影响其他容器。
  • 可移植性:容器可以在任何支持Docker的环境中运行。

例子:

  • 使用一个Node.js镜像运行两个相同的应用程序,每个应用程序在一个独立的容器中运行,相互隔离。

镜像托管平台:

DockerHub:

  • DockerHub 是一个 Docker 镜像的托管平台,类似于云存储,同时我们也可以在上面存储和分享自己的镜像。

其他镜像托管平台:

  • 除了DockerHub,国内也有一些类似的服务,如网易云镜像服务、阿里云镜像库等,它们提供了更快速、稳定的镜像下载服务,同时支持用户私有镜像的存储。另外我们也可以创建自己私有的镜像托管平台。

示意图:
镜像托管平台

总之,理解镜像和容器的关系,以及它们在 Docker 中的作用,是使用 Docker 进行应用开发和部署的基础。 Docker 的成功部分归功于这种轻量级、可移植的容器化技术,使得应用程序的构建、分发和运行变得更加简单和高效。

1.4 Docker的架构解析

Docker的架构设计简单而灵活,分为客户端和服务端两部分,它们协同工作以实现容器的创建、运行和管理。

客户端(Client)

客户端是用户与Docker交互的界面。用户可以通过命令行、图形界面或者使用 Docker 提供的API与服务端通信,发送指令来管理 Docker。

服务端(Server)

服务端是 Docker 的守护进程,负责处理来自客户端的指令,管理 Docker 的各项工作。服务端的主要组件包括:

  1. Docker Daemon: 守护进程,运行在主机上,负责管理容器的创建、运行和停止等操作。它还负责与其他Docker守护进程通信,以及与客户端通信。

  2. Docker REST API: 客户端和守护进程之间的通信通过REST API进行。客户端可以通过REST API向守护进程发送命令,实现与Docker的交互。

  3. Docker Registry: 用于存储Docker镜像的服务。Docker官方提供了Docker Hub作为默认的公共Registry,用户也可以使用私有Registry或其他公共Registry存储和分享镜像。

架构图示

Docker架构

在这个架构中,客户端和服务端可以运行在同一台主机上,也可以通过网络连接在不同的主机上。当客户端发送Docker命令时,它们通过REST API与服务端进行通信,服务端根据指令执行相应的操作。

交互流程

  1. 客户端发送命令: 用户通过命令行或其他工具发送Docker命令,如创建镜像、运行容器等。

  2. 命令发送至服务端: 客户端将命令发送至服务端,通过REST API进行通信。

  3. 服务端执行命令: Docker Daemon接收到命令后,执行相应的操作,如创建或管理容器、拉取或推送镜像等。

  4. 结果返回给客户端: 服务端执行完命令后,将结果返回给客户端,用户可以看到执行结果。

Docker的这种CS(Client-Server)架构使得用户可以通过简单的命令与Docker进行交互,同时服务端负责具体的管理和操作,使得整个系统更加模块化和易扩展。

1.5 Docker 在 CentOS 中的安装

Docker是一款强大的容器化平台,为了在CentOS上使用Docker,我们将按照以下步骤进行安装。

  1. 卸载旧版本(可选)

如果之前安装过 Docker 的旧版本,可以通过以下命令卸载:

sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce
  1. 安装依赖工具

安装必要的工具和依赖:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 添加 Docker 存储库

添加 Docker 的官方存储库。这里我们使用阿里云的镜像加速地址:

sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 安装 Docker 引擎

安装最新版本的 Docker 引擎:

sudo yum install docker-ce docker-ce-cli containerd.io
  1. 启动 Docker 引擎

启动 Docker 引擎并设置开机启动:

sudo systemctl start docker
sudo systemctl enable docker
  1. 验证安装

运行以下命令验证 Docker 是否正确安装:

docker --version
docker info
  1. 配置镜像加速

为了提升 Docker 镜像的下载速度,配置镜像加速器。以阿里云为例,前往阿里云容器镜像服务注册账号并获取加速地址。然后在/etc/docker/daemon.json中添加以下内容:

{"registry-mirrors": ["https://your-registry-mirror"]
}

替换https://your-registry-mirror为你的加速地址。

完成上述步骤后,我们的 CentOS 系统就成功安装并配置好了 Docker。现在,就可以通过运行 docker run hello-world 测试Docker是否正常工作。

二、Docker 的基本操作

Docker 的操作主要分为三个方面:镜像操作、容器操作和数据卷管理。下面详细介绍这三方面的相关命令。

2.1 操作 Docker 镜像命令

在Docker的世界中,镜像是应用程序的打包和分发单位。理解并熟练使用与镜像相关的命令是使用Docker的关键。本文将详细介绍一些常见的镜像操作命令。

2.1.1 镜像操作相关命令

镜像名称解析

在Docker中,镜像名称通常由两部分组成:[repository]:[tag]。如果不指定tag,默认使用latest,表示最新版本的镜像。例如,mysql的镜像名称:

镜像操作命令概览

从上图可以发现,镜像命令主要包括以下几种:

  1. docker pull 从远程仓库拉取镜像。

    docker pull image_name
    
  2. docker push 将本地镜像推送到远程仓库。

    docker push image_name
    
  3. docker build 根据Dockerfile构建镜像。

    docker build -t image_name .
    
  4. docker save 将镜像保存为一个tar压缩包。

    docker save -o image_name.tar image_name
    
  5. docker load 从一个tar压缩包中加载镜像。

    docker load -i image_name.tar
    

2.1.2 示例一:从 DockerHub 拉取一个 nginx 镜像

DockerHub是Docker官方的镜像仓库,提供了大量的官方和社区维护的镜像。以下是一个从 DockerHub 拉取nginx 镜像的示例:

docker pull nginx

上述命令将从 DockerHub 下载最新版本的 nginx 镜像到本地。然后使用 docker images命令则可以查看当前已经存在的镜像:

如果需要特定版本的镜像,可以使用:

docker pull nginx:version

version替换为需要的具体版本即可。

2.1.3 示例二:使用 save 将 nginx 镜像导出磁盘,然后再通过 load 加载回来

首先,关于 saveload 的语法,我们可以使用 --help 选项来进行查看:

save 命令:

docker save --help

可以发现,save 命令的作用是将镜像保存为一个tar格式的压缩包,使用 -o 选项代表STDOUT 标准输出,将其写入到文件中。

例如,保存上面的nginx镜像到磁盘:

docker save -o nginx.tar nginx:latest

load 命令:

docker load --help


可以发现,load 命令的作用是将一个tar格式的压缩包加载为一个 Docker 镜像,使用 -i 选项代表STDIN 标准输入,将其写入到指定文件中,-q 选项则不会输出日志到终端。

例如,加载刚才的 nginx.tar 压缩包:

首先删除nginx:latest镜像:

然后加载nginx.tar 压缩包:

2.2 Docker 容器命令详解

容器是Docker的运行实例,是镜像的具体执行环境。了解并熟练使用容器相关的命令是使用Docker的核心部分。接下来,我们将详细介绍一些常见的容器操作命令。

2.2.1 操作容器相关命令

容器操作命令如下图所示:

Docker容器操作命令

让我们逐一了解这些命令:

  1. docker run 运行容器。

    docker run options image_name
    
  2. docker pause 暂停容器。

    docker pause container_id
    

    此命令可以暂停运行中的容器,使其进程挂起。

  3. docker unpause 恢复容器。

    docker unpause container_id
    

    docker pause相对应,该命令用于恢复被暂停的容器。

  4. docker stop 停止容器。

    docker stop container_id
    

    通过此命令,你可以停止运行中的容器,但容器实例仍然存在。

  5. docker start 启动已停止的容器。

    docker start container_id
    

    使用该命令,你可以启动之前停止的容器。

  6. docker rm 移除容器。

    docker rm container_id
    

    通过此命令,你可以删除已经停止的容器实例。请注意,删除容器不会删除镜像。

  7. docker exec 在运行中的容器中执行命令。

    docker exec options container_id command
    

    该命令用于在正在运行的容器中执行特定命令,例如:

    docker exec -it container_id /bin/bash
    

    上述命令将在容器中打开一个交互式的bash shell。

  8. docker logs 查看容器日志。

    docker logs container_id
    

    此命令用于查看容器的输出日志。

  9. docker ps 列出运行中的容器。

    docker ps options
    

    通过此命令,可以列出正在运行的容器。使用-a选项可以列出所有容器,包括已停止的。

这些命令覆盖了 Docker 容器操作的核心方面,通过它们,可以方便地管理和使用 Docker 容器。在实践中,根据具体需求巧妙组合这些命令,可以更加高效地运行和管理容器。

补充:暂停pause和停止stop的区别说明:

docker pausedocker stop 是两个不同的命令,它们的作用分别是暂停容器和停止容器。下面分别说明它们之间的区别:

docker pause

  • 作用: 暂停容器的所有进程,冻结容器的状态。
  • 使用场景: 当希望保留容器的当前状态,但是暂时停止容器中的所有进程时,可以使用此命令。容器处于暂停状态时,其文件系统和内存中的数据仍然存在,但是容器内的所有进程都会被挂起,不再执行。
  • 例子:
    docker pause container_id
    

docker stop

  • 作用: 停止容器的运行,终止容器的所有进程。
  • 使用场景: 当希望完全终止容器的运行时,包括停止容器内的所有进程,释放占用的资源,可以使用此命令。容器处于停止状态时,可以选择删除容器或者重新启动。
  • 例子:
    docker stop container_id
    

区别总结:

  • docker pause 暂停容器,冻结容器状态,容器中的数据保留。
  • docker stop 停止容器,终止容器内的所有进程,容器中的数据保留。

在选择使用这两个命令时,需要根据具体的需求来决定。如果需要在保留容器状态的同时暂时停止容器中的所有进程,可以使用 docker pause;如果希望完全停止容器的运行,释放资源,可以使用 docker stop

2.2.2 示例一:运行 nginx 镜像

通过下面命令,可以在新的容器中运行一个 nginx镜像。例如:

docker run -d -p 8080:80 --name my-nginx nginx:latest

说明:

  • -d选项:让容器在后台运行;
  • -p选项:将宿主机的 8080 端口与容器的 80 端口进行映射,即访问宿主机的 8080 端口即可访问到容器的 80 端口;
  • --name选项:指定容器的名称,需要保证唯一;

    当运行成功之后,则会在终端中输出这个容器的唯一 ID。

可以使用 docker ps 命令查看当前运行中的容器:

另外,为了验证 nginx 容器成功启动并运行了,可以在浏览器中使用 宿主机IP:8080进行访问:


此时出现了 nginx 的欢迎页面,则说明成功启动并运行容器了。

2.2.3 示例二:进行 Nginx 容器内部,修改HTML文件内容

  1. 首先,我们可以使用 docker exec 命令进入容器的内容:
docker exec -it my-nginx bash

说明:

  • -it 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互;
  • my-nginx:要进入的容器的名称;
  • bash:开启 linux终端交互的命令。


此时的主机名变成了容器的部分 ID。

  1. 然后进入nginxHTML文件所在目录 /usr/share/nginx/html

  2. 修改index.html 文件的内容:

如果我们想要使用 vim 进行修改的话,发现 Docker 容器并没有提供 vim 编辑器,另外我们也可以发现其实 Docker 容器也只提供了少量的命令,原因在于保持容器的轻量化。

此时,我们可以使用 sed 命令进行修改:

# sed
sed -i 's#Welcome to nginx#Docker 非常简单!#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html # 修改编码方式为 UTF-8

  1. 再次在浏览器中进行访问:

2.3 操作 Docker 数据卷命令详解

2.3.1 容器与数据耦合的问题

在容器化应用中,容器与其数据之间的耦合可能带来一些问题:

  1. 不便于修改: 当需要修改容器内部的数据时,必须进入容器内部进行修改,这样不够方便。
  2. 数据不可复用: 对容器内数据的修改对外部是不可见的,新创建的容器无法复用这些修改。
  3. 升级维护困难: 如果数据在容器内,升级容器就意味着删除旧容器,所有数据都会被删除。

为了解决这些问题,可以使用 Docker 的数据卷。

2.3.2 什么是数据卷

数据卷(Volume)是一个可以在容器之间共享和重用的目录,它存在于宿主机而不是容器内。通过数据卷,将宿主机文件系统中的某个目录与容器中的目录进行映射,实现数据的共享和持久化。

如下图所示:
数据卷

可以发现,其实就是通过数据卷帮助宿主机文件系统中的文件与 Docker 容器中的文件建立了映射关系。

2.3.3 数据卷相关操作命令

Docker 提供了一系列的命令来管理数据卷,基本语法如下:

docker volume [COMMAND]

其中,COMMAND 可以是以下几个操作之一:

  • create: 创建一个数据卷。
  • inspect: 显示一个或多个数据卷的信息。
  • ls: 列出所有的数据卷。
  • prune: 删除未使用的数据卷。
  • rm: 删除一个或多个指定的数据卷。

下面将详细介绍其中的一些常用命令。

  1. 创建数据卷

要创建一个数据卷,可以使用 docker volume create 命令:

docker volume create my_volume

上述命令将创建一个名为 my_volume 的数据卷。

  1. 查看数据卷信息

使用 docker volume inspect 命令可以查看一个或多个数据卷的详细信息:

docker volume inspect my_volume
  1. 列出所有数据卷

使用 docker volume ls 命令可以列出所有的数据卷:

docker volume ls
  1. 删除数据卷

要删除一个或多个指定的数据卷,可以使用 docker volume rm 命令:

docker volume rm my_volume
  1. 清理未使用的数据卷

使用 docker volume prune 命令可以删除未被使用的数据卷:

docker volume prune

上述命令将提示是否删除未使用的数据卷,确认后将执行删除操作。

通过这些数据卷的管理命令,可以更加灵活地处理容器中的数据,实现数据的持久化和共享。在实际应用中,数据卷是非常有用的特性,尤其是对于需要持久化存储的应用场景。

2.3.4 示例一:创建一个数据卷,并查看数据卷在宿主机的目录位置

  1. 创建数据卷
docker volume create html


2. 查看当前所有的数据卷

docker volume ls

  1. 查看数据卷 html 的详细信息
docker volume inspect html

可以发现,html 的宿主机中的挂载点为:/var/lib/docker/volumes/html/_data

2.3.5 示例二:创建nginx容器的同时创建数据卷,通过数据卷修改 HTML 内容

我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器目录:

docker run \--name my-nginx \-v html:/usr/share/nginx/html \-p 8080:80 \-d \nginx:latest

  1. 进入html数据卷所在位置

  2. 并修改 index.html 内容

  3. 通过浏览器访问 nginx

    此时便成功通过数据卷的方式对 Docker 容器内容的文件进行了修改了。

三、Dockerfile 自定义镜像的创建

3.1 镜像文件的结构详解

Docker 镜像是一个包含应用程序及其运行所需组件的轻量级、可执行的软件包。它的文件结构是分层的,每一层都包含了对文件系统的一些更改。让我们深入了解镜像文件的结构。

  1. 镜像的层次结构

镜像的层次结构由多个层组成,如下图所示:

镜像层次结构

这些层次分为以下几类:

  1. Base Image 层: 包含基本的系统函数库、环境变量和文件系统。这一层构成了镜像的基础。

  2. Entrypoint 层: 包含应用程序的启动命令。它定义了镜像中应用程序的入口点。

  3. 其它层: 在 Base Image 的基础上添加应用程序的依赖、安装程序等,完成整个应用的安装和配置。每一层都是基于前一层的修改。

  1. 镜像的分层优势

Docker 镜像采用分层的设计有一些优势:

  • 高效的存储利用: 如果多个镜像共享相同的基础层,这一层只需要存储一次,减少了存储空间的占用。

  • 快速的分发: 镜像的分层结构也使得只需要传输发生更改的层,而不是整个镜像,因此可以更快速地分发和部署。

通过这样的分层结构,Docker 实现了镜像的高效管理、存储和传输,使得容器的构建和分发变得更加轻量和快速。

3.2 Dockerfile 文件详解

  1. 什么是 Dockerfile

Dockerfile 是 Docker 中用于构建镜像的脚本文件,它包含了一系列指令,每个指令都会在当前层次上进行修改,形成一个新的层次,最终组合成一个完整的容器镜像。

  1. Dockerfile 指令

以下是一些常用的 Dockerfile 指令及其说明:

指令说明示例
FROM指定基础镜像,后续的指令将基于这个镜像构建。FROM centos:7
ENV设置环境变量,这些变量可在后续指令中使用。ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk
COPY将文件从构建上下文复制到镜像中的指定路径。COPY ./app.jar /usr/app/
RUN执行 Linux 的 shell 命令,一般用于安装软件包等操作。RUN yum install -y gcc
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的。EXPOSE 8080
ENTRYPOINT指定容器中应用的启动命令,容器运行时会调用这个命令。ENTRYPOINT ["java", "-jar", "app.jar"]

更多 Dockerfile 指令和语法细节可以参考官方文档:Dockerfile reference

  1. Dockerfile 文件

在构建 Docker 镜像时,Docker 会按照 Dockerfile 中的指令逐层构建镜像。每个指令都会在当前层次上进行修改,形成一个新的层次。

例如一个简单的 Dockerfile 如下:

# 使用基础镜像
FROM ubuntu:latest# 执行一些命令
RUN apt-get update && apt-get install -y \nginx \&& rm -rf /var/lib/apt/lists/*# 设置工作目录
WORKDIR /app# 复制文件
COPY . .# 设置入口命令
CMD ["nginx", "-g", "daemon off;"]

在这个例子中,每一个指令都会在前一个指令的基础上进行修改,构建出一个包含了基础镜像、安装了 Nginx、设置了工作目录和入口命令的完整镜像。

  1. 使用 Dockerfile 构建镜像

在构建 Docker 镜像时,通过以下命令使用 Dockerfile:

docker build -t my-image:tag path/to/Dockerfile-context
  • -t:指定镜像的名称和标签。
  • path/to/Dockerfile-context:Dockerfile 所在的上下文路径。

例如,在一个包含 Dockerfile 的目录中运行以下命令:

docker build -t my-app:1.0 .

上述命令将在当前目录中查找 Dockerfile 文件并构建一个名为 my-app、标签为 1.0 的镜像。

3.3 示例一:基于 Ubuntu 镜像构建一个新镜像,运行一个 Java 项目

  1. 准备工作
  • 步骤1:新建一个空文件夹 docker-demo

Step 1

  • 步骤2:拷贝 Java 项目文件

拷贝提前准备好的 Java jar 包 docker-demo.jar 文件到 docker-demo 这个目录

Step 2

  • 步骤3:拷贝 JDK 文件

拷贝提前准备的 jdk8.tar.gz 文件到 docker-demo 这个目录

Step 3

  1. 编写 Dockerfile

docker-demo 这个目录下,编写一个 Dockerfile 文件,其内容如下:

# 指定基础镜像
FROM ubuntu:16.04# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local# 拷贝 JDK 和 Java 项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar# 安装 JDK
RUN cd $JAVA_DIR \&& tar -xf ./jdk8.tar.gz \&& mv ./jdk1.8.0_144 ./java8# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin# 暴露端口
EXPOSE 8090# 入口,Java 项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
  1. 构建和运行 Docker 镜像

docker-demo 目录下,执行以下命令构建 Docker 镜像:

docker build -t java-app:1.0 .

Build Image

运行这个镜像:

docker run -d -p 8090:8090 --name java-app java-app:1.0

Run Container

最后在浏览器中访问: http://宿主机IP:8090/hello/count

Browser

通过这个示例,我们成功地基于 Ubuntu 镜像构建了一个包含 Java 项目的镜像,并运行了一个容器。这展示了 Dockerfile 的使用以及如何在容器中运行 Java 应用程序。

3.4 示例二:基于 java:8-alpine 镜像,修改示例一的 Dockerfile 文件

在示例一中,我们使用了 Ubuntu 作为基础镜像。这一示例中,我们将使用 java:8-alpine 作为基础镜像,这是一个更轻量级的镜像,适用于精简容器体积的场景。

什么是 java:8-alpine

java:8-alpine 是一个基于 Alpine Linux 发行版的 Docker 镜像,专门用于运行 Java 应用程序。让我们拆解这个标签的含义:

  • java:这表示这个镜像是为 Java 应用程序准备的。
  • 8:这表示 Java 版本,具体是 Java 8。
  • alpine:这表示基础操作系统是 Alpine Linux。Alpine Linux 是一个轻量级的 Linux 发行版,以小巧、简单而闻名。

Alpine Linux 与传统的 Linux 发行版相比,更注重精简和安全。它的包管理系统采用 apk,而不是像 Ubuntu 和 CentOS 那样使用 aptyum。由于精简的设计,Alpine Linux 提供了更小的镜像体积,这对于容器化应用来说非常重要。

因此,java:8-alpine 镜像是一个非常适合运行 Java 应用程序的轻量级选择。

  1. 修改 Dockerfile

docker-demo 目录下,修改 Dockerfile 文件如下:

# 指定基础镜像
FROM java:8-alpine# 拷贝 Java 项目的包
COPY ./docker-demo.jar /tmp/app.jar# 暴露端口
EXPOSE 8090# 入口,Java 项目的启动命令
CMD ["java", "-jar", "/tmp/app.jar"]
  1. 重新构建和运行 Docker 镜像

docker-demo 目录下,执行以下命令重新构建 Docker 镜像:

docker build -t java-app:2.0 .

运行这个镜像:

docker run -d -p 8090:8090 --name java-app-alpine java-app:2.0

最后在浏览器中访问: http://宿主机IP:8090/hello/count

通过这个示例,我们成功地使用了 java:8-alpine 作为基础镜像,实现了相同的 Java 项目运行。这样的修改不仅提高了容器的轻量级,同时也减小了镜像体积。

相关文章:

【Docker】初识 Docker,Docker 基本命令的使用,Dockerfile 自定义镜像的创建

文章目录 前言&#xff1a;项目部署的挑战一、初识 Docker1.1 什么是 Docker1.2 Docker 与 虚拟机的区别1.3 镜像和容器以及镜像托管平台1.4 Docker的架构解析1.5 Docker 在 CentOS 中的安装 二、Docker 的基本操作2.1 操作 Docker 镜像命令2.1.1 镜像操作相关命令2.1.2 示例一…...

【Docker】简易版harbor部署

文章目录 依赖于docker-compose下载添加执行权限测试 安装harbor下载解压修改配置文件部署配置开机自启动登录验证 使用harbor登录打标签上传下载 常见问题 依赖于docker-compose 下载 curl -L “https://github.com/docker/compose/releases/download/2.22.0/docker-compose-…...

Zookeeper经典应用场景实战(一)

文章目录 1、Zookeeper Java客户端实战1.1、 Zookeeper 原生Java客户端使用1.2、 Curator开源客户端使用 2、 Zookeeper在分布式命名服务中的实战2.1、 分布式API目录2.2、 分布式节点的命名2.3、 分布式的ID生成器 3、Zookeeper实现分布式队列3.1、 设计思路3.2、 使用Apache …...

Chrome报错:Unchecked runtime.lastError

项目背景、安装了 Express 框架&#xff0c;目的是为了快速创建一个web服务器。创建成功后&#xff0c;控制台出现了报错&#xff0c;而在这之前没有出现过这个错误&#xff0c;所以一直在纠结是不是框架本身的问题。 错误原因&#xff1a;这个错误一般是浏览器与扩展或者插件…...

【算法】算法设计与分析 课程笔记 第三章 动态规划

1.1 动态规划简介 1.1.1 引例 动态规划算法和分治法类似&#xff0c;基本思想也是将待求解问题分解成若干个子问题&#xff0c;子问题可以以继续拆分&#xff0c;直到问题规模达到临界条件即可。多说无益&#xff0c;举个例子来解释一下&#xff1a; 这其实是一个多阶段图求最…...

贪心找性质+dp表示+矩阵表示+线段树维护:CF573D

比较套路的题目 首先肯定贪心一波&#xff0c;两个都排序后尽量相连。我一开始猜最多跨1&#xff0c;但其实最多跨2&#xff0c;考虑3个人的情况&#xff1a; 我们发现第3个人没了&#xff0c;所以可以出现跨2的情况 然后直接上dp&#xff0c;由 i − 1 , i − 2 , i − 3 i…...

小谈设计模式(17)—状态模式

小谈设计模式&#xff08;17&#xff09;—状态模式 专栏介绍专栏地址专栏介绍 状态模式关键角色上下文(Context)抽象状态(State)具体状态(Concrete State) 核心思想Java程序实现首先&#xff0c;我们定义一个抽象状态类 State&#xff0c;其中包含一个处理请求的方法 handleRe…...

Arm64体系架构-MPIDR_EL1寄存器

背景 在Arm64多核处理器中, 各核间的关系可能不同. 比如1个16 core的cpu, 每4个core划分为1个cluster,共享L2 cache. 当我们需要从core 0将任务调度出来时,如果优先选择core 1~3, 那么性能明显时优于其他core的. 那么操作系统怎么知道core之间这样的拓扑信息呢? Arm提供了MPID…...

MySQL支持哪些存储引擎

mysql支持九大存储引擎&#xff1a; 1&#xff09;MYISAM存储引擎&#xff08;优点&#xff1a;可被转换为压缩、只读表来节省空间。&#xff09; 它管理的表具有以下特征&#xff1a; 使用三个文件表示每个表 格式文件-存储表结构的定义&#xff08;mytable.frm) 数据文件-存…...

ElementUI结合Vue完成主页的CUD(增删改)表单验证

目录 一、CUD ( 1 ) CU讲述 ( 2 ) 编写 1. CU 2. 删除 二、验证 前端整合代码 : 一、CUD 以下的代码基于我博客中的代码进行续写 : 使用ElementUI结合Vue导航菜单和后台数据分页查询 ( 1 ) CU讲述 在CRUD操作中&#xff0c;CU代表创建&#xff08;Create&#xff09…...

Flutter开发笔记 —— 语音消息功能实现

前言 最近在开发一款即时通讯(IM)的聊天App&#xff0c;在实现语音消息功能模块后&#xff0c;写下该文章以做记录。 注&#xff1a;本文不提供相关图片资源以及IM聊天中具体实现代码&#xff0c;单论语音功能实现思路 需求分析 比起上来直接贴代码&#xff0c;我们先来逐步…...

冒泡排序和选择排序

目录 一、冒泡排序 1.冒泡排序的原理 2.实现冒泡排序 1.交换函数 2.单躺排序 3.冒泡排序实现 4.测试 5.升级冒泡排序 6.升级版代码 7.升级版测试 二、选择排序 1.选择排序的原理 2.实现选择排序 1.单躺排序 2.选择排序实现 3.测试 ​4.修改 5.测试 一、冒泡排序…...

【深度学习】UNIT-DDPM核心讲解

文章目录 大致介绍&#xff1a;扩散损失&#xff1a;转换损失&#xff1a;循环一致性损失&#xff1a;推理过程&#xff1a;优缺点&#xff1a; 参考文章&#xff1a; https://blog.csdn.net/ssshyeong/article/details/127210086 这篇文章对整个文章 UNIT-DDPM: UNpaired Imag…...

Java 线程的优先级

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

金融数学方法:牛顿法

目录 1.牛顿法1.1 牛顿法介绍1.2 算法步骤 2. 具体算例3.总结 1.牛顿法 1.1 牛顿法介绍 牛顿法&#xff08;Newton’s method&#xff09;&#xff0c;也被称为牛顿-拉夫森方法&#xff08;Newton-Raphson method&#xff09;&#xff0c;是一种用于数值逼近根的迭代方法。它是…...

MongoTemplate | 多条件查询

MongoTemplate查询 Resource private MongoTemplate mongoTemplate;public <T> List<T> getDataList(String param1, Long param2, Class<T> clazz) {// 构建queryQuery query constructQuery(param1, param2);// 查询return mongoTemplate.find(query, cl…...

优秀程序员是怎么思考的?

首发日更公 Z 号&#xff1a;十二又十三 作为一名优秀的程序员&#xff0c;思考是我们工作中最重要的一部分。它不仅能够帮助我们解决问题&#xff0c;还能够提升我们的技术水平和职业发展。那么&#xff0c;优秀程序员是如何思考的呢&#xff1f;本文将为您介绍一个思考框架和…...

【juc】countdownlatch实现游戏进度

目录 一、截图示例二、代码示例 一、截图示例 二、代码示例 package com.learning.countdownlatch;import java.util.Arrays; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurr…...

Spring Webflux HttpHandler源码整理

HttpHandler的构造 自动启动配置类&#xff1a;HttpHandlerAutoConfigurationBean public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {HttpHandler httpHandler WebHttpHandlerBuilder.applicationContext(this.applicationContext).…...

Qt扩展-Advanced-Docking 简介及配置

Advanced-Docking 简介及配置 一、概述二、项目结构三、安装配置四、代码测试 一、概述 Advanced-Docking 是类似QDockWidget 功能的多窗口停靠功能的库。很像visual stdio 的 停靠功能&#xff0c;这个库对于停靠使用的比较完善。很多的软件都使用了这个框架。 项目源地址&a…...

Decorator

Decorator 动机 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”&#xff0c; 由于继承为类型引入的静态特质&#xff0c;使得这种扩展方式缺乏灵活性&#xff1b; 并且随着子类的增多&#xff08;扩展功能的增多&#xff09;&#xff0c;各种子类的组合&#xff…...

分布式文件系统HDFS(林子雨慕课课程)

文章目录 3. 分布式文件系统HDFS3.1 分布式文件系统HDFS简介3.2 HDFS相关概念3.3 HDFS的体系结构3.4 HDFS的存储原理3.5 HDFS数据读写3.5.1 HDFS的读数据过程3.5.2 HDFS的写数据过程 3.6 HDFS编程实战 3. 分布式文件系统HDFS 3.1 分布式文件系统HDFS简介 HDFS就是解决海量数据…...

CSS中:root伪类的使用

在CSS中&#xff0c;:root是一个伪类选择器&#xff0c;它选择的是文档树的根元素。在HTML文档中&#xff0c;这个根元素通常是<html>。:root伪类选择器常常被用于定义全局的CSS变量或者设置全局的CSS样式。 例如&#xff0c;你可以使用:root来定义一个全局的字体大小&a…...

VulnHub JANGOW

提示&#xff08;主机ip分配问题&#xff09; 因为直接在VulnHub上下载的盒子&#xff0c;在VMware上打开&#xff0c;默认是不分配主机的 所以我们可以在VirtualBox上打开 一、信息收集 发现开放了21和80端口&#xff0c;查看一下80端口 80端口&#xff1a; 检查页面后发现…...

OpenMesh 获取网格面片各个顶点

文章目录 一、简介二、实现代码三、实现效果一、简介 OpenMesh中有很多循环器,这里便是其中一种面顶点循环器,以此来获得面片的各个顶点。 二、实现代码 #define _USE_MATH_DEFINES #include <iostream> #include <unordered_map>...

【前端设计模式】之原型模式

原型模式特性 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过克隆现有对象来创建新对象&#xff0c;而不是通过实例化类。原型模式的主要特性包括&#xff1a; 原型对象&#xff1a;原型对象是一个已经存在的对象&#xff0c;它作…...

软件设计原则

设计原则 一、单一原则 1. 如何理解单一职责原则 单一职责原则&#xff08;Single Responsibility Principle&#xff0c;简称SRP&#xff09;&#xff0c;它要求一个类或模块应该只负责一个特定的功能。实现代码的高内聚和低耦合&#xff0c;提高代码的可读性和可维护性。 …...

【面试HOT100】哈希双指针滑动窗口

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于LeetCodeHot100进行的&#xff0c;每个知识点的修正和深入主要参考…...

Ubuntu20.04 配置 yolov5_ros 功能包记录

文章目录 本文参考自博主源801,结合自己踩坑后修改 项目地址:https://github.com/mats-robotics/yolov5_ros 1.新建工作空间 新建一个工作空间 yolo_ros(名字可自定义),在 yolo_ros 下新建文件夹 src 并catkin_make进行编译 2. 安装相机驱动,可以选用较为主流的 usb_cam 或…...

Flink的处理函数——processFunction

目录 一、处理函数概述 二、Process函数分类——8个 &#xff08;1&#xff09;ProcessFunction &#xff08;2&#xff09;KeyedProcessFunction &#xff08;3&#xff09;ProcessWindowFunction &#xff08;4&#xff09;ProcessAllWindowFunction &#xff…...