Docker
Docker
是一种容器化平台,允许你将应用程序和它们的所有依赖项打包到一个独立的容器中,以便在不同环境中进行分发和部署。以下是一些使用 Docker
的主要优点:
-
跨平台性 :
Docker
容器可以在不同的操作系统上运行,包括Linux
、Windows
和macOS
。这意味着你可以在开发、测试和生产环境之间轻松地迁移容器,而不必担心环境差异。 -
隔离性 :
Docker
使用容器技术,可以将应用程序和依赖项隔离在一个独立的容器中。这种隔离性确保了容器之间互不干扰,使得你可以同时运行多个容器,而不必担心冲突。 -
一致性 :
Docker
容器包含了应用程序和其依赖项的所有组件,包括库、配置文件和环境变量。这确保了在不同环境中运行时的一致性,消除了 "在我的机器上可以工作" 这种问题。 -
易于部署和扩展 :
Docker
容器可以快速部署到云上或本地服务器上,而不必手动配置环境。容器也可以轻松地扩展,以应对流量增加的需求。 -
版本控制 :
Docker
允许你创建和管理容器的版本,以便回滚或恢复到以前的版本。这有助于追踪应用程序的演化和修复问题。 -
生态系统 :
Docker
生态系统丰富,有许多容器可以在Docker Hub
或其他容器注册表中找到。这些容器包含了各种开源应用程序、服务和工具,可以加速应用程序的开发和部署。 -
资源利用 :
Docker
容器共享宿主操作系统的内核,因此在资源利用方面更加高效,相比于虚拟机,启动和停止容器更加迅速。
总之,Docker
提供了一种便捷、可移植、可伸缩和一致的方式来构建、交付和运行应用程序。这使得开发团队能够更快地交付软件,并更容易维护和管理应用程序的生命周期。因此,许多开发人员和组织选择使用 Docker
来改善其应用程序的开发和部署流程。
三要素
Docker
包括三个基本概念:
- Docker 镜像(Image):
-
Docker 镜像是一个轻量级、可执行的软件包,其中包含了应用程序的代码、运行时环境、系统工具和库以及配置文件。
-
镜像是只读的,不可更改的,一旦创建,它的内容将保持不变。如果需要修改,通常需要通过构建一个新的镜像来实现。
-
镜像是容器的基础,容器是从镜像中创建的运行实例。
-
镜像可以通过
Dockerfile
文件来定义和构建,Dockerfile
是一个文本文件,包含了构建镜像所需的指令和配置。 -
镜像可以通过
Docker Hub
、私有Docker
仓库或其他容器仓库来共享和分发。
- Docker 容器(Container):
-
Docker
容器是Docker
镜像的运行实例,它是一个独立的、轻量级的虚拟环境,包括了应用程序及其依赖项。 -
容器是可运行和可启动的,可以像进程一样在宿主操作系统上运行。
-
每个容器都是相互隔离的,具有自己的文件系统、网络空间和进程空间。这种隔离性使得容器可以在相同的宿主系统上同时运行多个容器,而不会相互干扰。
-
容器的生命周期可以管理,包括创建、启动、停止、删除等操作。
-
容器可以在不同的环境中移植,因为它们包含了所有运行所需的依赖项,保证了应用程序在不同的环境中一致运行。
- Docker 仓库(Repository):
-
Docker
仓库是用于存储、共享和管理Docker
镜像的地方。 -
仓库可以是公共的(
Public Repository
)或私有的(Private Repository
)。 -
公共仓库,如
Docker Hub
,是全球开放的镜像存储和分享平台,包含了大量的官方和社区维护的镜像。 -
私有仓库是用于存储敏感或专有镜像的地方,可以在自己的服务器上搭建或使用云服务提供的容器镜像存储服务。
-
仓库中的镜像可以通过标签(
Tag
)来区分不同版本或配置,例如nginx:latest
。 -
你可以从仓库中拉取(下载)镜像到本地,也可以将自己构建的镜像推送(上传)到仓库中,以供他人使用。
总之,Docker
的镜像、容器和仓库是构建、分发和运行容器化应用程序的核心概念。它们提供了一种便捷、可移植、可扩展和一致的方式来处理应用程序的依赖关系和运行环境。使用 Docker
,开发人员和运维人员可以更轻松地管理和部署应用程序,从而提高开发和运维的效率。
常用命令
获取镜像
从 Docker
镜像仓库获取镜像的命令是 docker pull
。其命令格式为:
bash
$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
比如我们获取ubuntu
镜像,没有给的docker
镜像地址,默认从Docker Hub
获取镜像
bash
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
92dc2a97ff99: Pull complete
be13a9d27eb8: Pull complete
c8299583700a: Pull complete
Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
运行镜像
有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 ubuntu:18.04
为例,如果我们打算启动里面的 bash
并且进行交互式操作的话,可以执行下面的命令。
bash
$ docker run -it --rm ubuntu:18.04 bash
root@e7009c6ce357:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
docker run
就是运行容器的命令,解释一下上面的命令
-
-it
:这是两个参数,一个是-i
:交互式操作,一个是-t
终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。 -
--rm
:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动docker rm
。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用--rm
可以避免浪费空间。 -
ubuntu:18.04
:这是指用ubuntu:18.04
镜像为基础来启动容器。 -
bash
:放在镜像名后的是 命令,这里我们希望有个交互式Shell
,因此用的是bash
列出本地已有镜像
想列出已经下载下来的镜像,可以使用 docker image ls 命令。
bash
$ docker image ls
列出部分镜像
不加任何参数的情况下,docker image ls
会列出所有顶层镜像,但是有时候我们只希望列出部分镜像。docker image ls
有好几个参数可以帮助做到这个事情
bash
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 329ed837d508 3 days ago 63.3MB
ubuntu bionic 329ed837d508 3 days ago 63.3MB
其他镜像操作命令
其他的镜像操作命令可以使用--help
进行查看
bash
docker image ls --help
Usage: docker image ls [OPTIONS] [REPOSITORY[:TAG]]
List images
Aliases:
ls, list
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs
删除本地镜像
如果要删除本地的镜像,可以使用 docker image rm
命令,其格式为:
bash
$ docker image rm [选项] <镜像1> [<镜像2> ...]
你也可是使用 ID
、镜像名、摘要删除镜像
bash
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest ab73c7fd6723 3 weeks ago 192MB
ubuntu latest a2f229f811bf 5 weeks ago 69.2MB
根据IMAGE ID
删除,可以是整个id
,也可以使用简短的id
一般取前3
个字符以上,只要足够区分于别的镜像就可以了。比如这里,如果我们要删除 nginx
镜像,可以执行:
bash
$ docker image rm ab7
Untagged: nginx:latest
Untagged: nginx@sha256:104c7c5c54f2685f0f46f3be607ce60da7085da3eaa5ad22d3d9f01594295e9c
Deleted: sha256:ab73c7fd672341e41ec600081253d0b99ea31d0c1acdfb46a1485004472da7ac
Deleted: sha256:84ea63b436b2e500b5f70e39d540ff32ac8848f7cfbee7e0a5f56ede4bbd9aae
Deleted: sha256:6e4f4d7712f59078f77653b1629296eea47fad80251d492c411109eb8a627f65
Deleted: sha256:76537c195838a2622cf9f1742d0c03e00f3493655589bdaf6d476d4772f11382
Deleted: sha256:f7ee0b034b33fb35400b16e242b7fc26b0d94f20e56b6542a7333a957cd5e511
Deleted: sha256:25cd8e7142cdb22583264d650a19b2aed7262dc20a4321fc1f9cfaea59dfd64f
Deleted: sha256:5cfc11224748582651f8d0669aaf50242d094c0a6999924a54ac450d8096d2e4
Deleted: sha256:1c3daa06574284614db07a23682ab6d1c344f09f8093ee10e5de4152a51677a1
当然也可以使用镜像名进行删除
bash
docker image rm ubuntu
构建镜像
使用Dockerfile
进行镜像构建
使用了 docker build
命令进行镜像构建。其格式为:
bash
docker build [选项] <上下文路径/URL/->
不知道如何使用和选项有些什么我们可以使用help
命令查看
bash
$ docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is
'PATH/Dockerfile')
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
--network string Set the networking mode for the RUN
instructions during build (default "default")
--no-cache Do not use cache when building the image
-o, --output stringArray Output destination (format:
type=local,dest=path)
--platform string Set platform if server is multi-platform
capable
--progress string Set type of progress output (auto, plain,
tty). Use plain to show container output
(default "auto")
--pull Always attempt to pull a newer version of
the image
-q, --quiet Suppress the build output and print image
ID on success
--secret stringArray Secret file to expose to the build (only
if BuildKit enabled):
id=mysecret,src=/local/secret
--ssh stringArray SSH agent socket or keys to expose to the
build (only if BuildKit enabled) (format:
default|<id>[=<socket>|<key>[,<key>]])
-t, --tag list Name and optionally a tag in the
'name:tag' format
--target string Set the target build stage to build.
我们写一个静态资源服务器来简单演示下如何使用Dockerfile
进行镜像构建
bash
$ mkdir dockerfile-test
$ cd dockerfile-test
$ yarn init -y
yarn init v1.22.18
warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.
success Saved package.json
✨ Done in 0.02s.
$ touch Dockerfile
$ touch .dockerignore
$ mkdir src
$ mkdir public
$ cd src
$ touch server.js
$ cd ..
$ cd public
$ touch index.html
$ cd ..
$ yarn add express -S
到目前为止,我们就创建好了一个项目的基础目录,执行 tree -a
可以看到现在的目录如下
bash
├── .dockerignore
├── Dockerfile
├── package.json
├── public
│ └── index.html
└── src
└── server.js
接下来我们来填充下各个文件
html
// public/index.html
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
改造src/server.js
使用express
启动一个服务
js
// src/server.js
const express = require('express');
const { resolve } = require('path');
const server = express();
const port = parseInt(process.env.PORT || '8080');
const publicDir = resolve('public');
server.use(express.static(publicDir));
server.listen(port, () => console.log(`Listening on port ${port}`));
改造package.json
在 package.json
中设置启动脚本:
json
// package.json
{
"name": "dockerfile-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node src/server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
}
}
.dockerignore
类似于.gitignore
,使用.dockerignore
可以限制 copy
到容器内的文件,这样一些和容器内app
运行无关的文件就不会被复制到容器内。
.dockerignore
// .dockerignore
node_modules
启动服务yarn start
bash
$ yarn start
不出意外,打开http://localhost:8080
,你就能看见一下画面。
好了,服务可以启动起来了,我们使用dockerfile
进行镜像构建。
安装 Docker
Docker 作为主流容器技术必须熟练掌握,可以在官网下载并安装。
编写dockerfile
文件
dockerfile
FROM node:18-alpine
WORKDIR /usr/app/dockerfile-test
COPY . .
RUN yarn
EXPOSE 8080
CMD yarn start
这是一个用于构建 Docker
镜像的简单 Node.js
应用程序的 Dockerfile
。让我为您解释每个步骤的作用:
-
FROM node:18-alpine
: 这个指令从官方Node.js
镜像中选择一个指定版本(18)的Alpine Linux
版本。Alpine Linux
是一个轻量级的Linux
发行版。 -
WORKDIR /usr/app/dockerfile-test
: 设置工作目录为/usr/app/dockerfile-test
,后续的命令都将在这个目录下执行。 -
COPY . .
: 将当前目录(Dockerfile
所在的目录)的所有内容复制到容器的工作目录中。 -
RUN yarn
: 在容器中执行yarn
命令,用于安装项目的依赖。前提是在项目根目录下有一个有效的package.json
文件,并且其中定义了依赖关系。 -
EXPOSE 8080
: 声明容器将会在运行时监听的网络端口,这里是8080
。请注意,这仅仅是一种文档形式,用于说明该容器服务会使用这个端口,实际上并不会自动映射这个端口。 -
CMD yarn start
: 指定容器启动时默认执行的命令。在这里,它是yarn start
,是启动Node.js
应用程序的命令。
使用构建命令进行构建
bash
$ # 构建容器镜像,命名为 dockerfile-test,标签为 1.0
$ docker build -t dockerfile-test:1.0 .
[+] Building 11.5s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 135B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 32B 0.0s
=> [internal] load metadata for docker.io/library/node:18-alpine 6.5s
=> [1/4] FROM docker.io/library/node:18-alpine@sha256:3482a20c97e401b56a 0.0s
=> [internal] load build context 0.4s
=> => transferring context: 2.05MB 0.4s
=> CACHED [2/4] WORKDIR /usr/app/00-static 0.0s
=> [3/4] COPY . . 0.2s
=> [4/4] RUN yarn 4.0s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:fc2afda24748cb59e0f38f197578bc000bf7a63a19aca 0.0s
=> => naming to docker.io/library/dockerfile-test:1.0 0.0s
到这,我们就基于Dockerfile
构建出了一个dockerfile-test
镜像,标签为 1.0
,使用docker image ls
可以看到我么构建的这个镜像。接下来我们来运行这个镜像使用docker run
命令。
bash
$ # 以镜像 dockerfile-test:1.0 运行容器,命名为 dockerfile-test
$ docker run -p 9090:8080 -d --name dockerfile-test dockerfile-test:1.0
打开http://localhost:8080
,我们也能够看到和之前一样的页面Hello world
。
Dockerfile常用指令
以下是一些常用的 Dockerfile
指令以及它们的用法,使用表格形式列出:
以下是一些常用的 Dockerfile
指令以及它们的用法,使用表格形式列出:
指令 | 用法及描述 |
---|---|
FROM |
FROM <base_image> 指定基础镜像,作为新镜像的基础。 |
MAINTAINER |
MAINTAINER <author> 设置作者信息,标识镜像的作者。 |
RUN |
RUN <command> 在镜像构建过程中执行命令,安装软件包、配置环境等。 |
WORKDIR |
WORKDIR /path/to/directory 设置工作目录,后续命令将在该目录下执行。 |
COPY |
COPY <source> <destination> 复制文件或目录到镜像中。 |
ADD |
ADD <source> <destination> 类似于 COPY,但支持更多功能(如 URL 下载、解压缩等)。 |
ENV |
ENV <key> <value> 设置环境变量,用于配置容器内部的环境。 |
EXPOSE |
EXPOSE <port> 指定容器监听的端口号,用于声明容器将要监听的端口。 |
CMD |
CMD ["executable","param1","param2"] 容器启动时执行的默认命令,可被覆盖。 |
ENTRYPOINT |
ENTRYPOINT ["executable", "param1", "param2"] 容器启动时执行的默认入口点命令,不可被覆盖。 |
VOLUME |
VOLUME ["/data"] 创建挂载点,用于持久化数据,通常用于容器与宿主机的数据共享。 |
USER |
USER <username> 指定运行容器的用户名或 UID,用于切换用户身份。 |
LABEL |
LABEL <key>=<value> 添加元数据标签,用于注释和标识镜像。 |
ARG |
ARG <name>=<value> 定义构建时传递给镜像的参数,可在构建时覆盖默认值。 |
ONBUILD |
ONBUILD <instruction> 定义触发器指令,用于构建镜像时的操作,将在子镜像构建过程中执行。 |
SHELL |
SHELL ["/bin/bash", "-c"] 指定 shell 的类型和参数,用于执行 RUN 命令的默认 shell。 |
这些 Dockerfile
指令用于定义镜像构建过程中的各种操作,允许你自定义容器的环境、安装依赖、配置应用程序等。根据你的具体需求,可以组合使用这些指令来创建定制的 Docker
镜像。要了解更多关于这些指令的详细信息和示例用法,请查阅 Docker
官方文档或相关教程。
这些 Dockerfile
指令用于定义镜像构建过程中的各种操作,允许你自定义容器的环境、安装依赖、配置应用程序等。根据你的具体需求,可以组合使用这些指令来创建定制的 Docker
镜像。要了解更多关于这些指令的详细信息和示例用法,请查阅 Docker 官方文档或相关教程。
容器
启动
启动所需要的命令主要为 docker run
。比如上面的以镜像 dockerfile-test:1.0
运行容器,命名为 dockerfile-test
bash
$ docker run -p 9090:8080 -d --name dockerfile-test dockerfile-test:1.0
在 Docker
中,你可以使用一系列命令来管理容器,包括创建、启动、停止、删除、查看日志等。以下是一些常用的容器操作命令:
- 创建容器:
bash
$ docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
例如,创建一个名为 "my-container
" 的容器:
bash
$ docker create --name my-container ubuntu:20.04
- 启动容器:
bash
$ docker start [OPTIONS] CONTAINER [CONTAINER...]
例如,启动名为 "my-container" 的容器:
bash
$ docker start my-container
- 停止容器:
bash
$ docker stop [OPTIONS] CONTAINER [CONTAINER...]
例如,停止名为 "my-container" 的容器:
bash
$ docker stop my-container
- 删除容器:
bash
$ docker rm [OPTIONS] CONTAINER [CONTAINER...]
例如,删除名为 "my-container" 的容器:
bash
$ docker rm my-container
- 查看运行中的容器:
bash
$ docker ps [OPTIONS]
例如,查看所有运行中的容器:
bash
$ docker ps
- 查看所有容器(包括停止的):
bash
$ docker ps -a
- 查看容器日志:
bash
$ docker logs [OPTIONS] CONTAINER
例如,查看名为 "my-container" 的容器的日志:
bash
$ docker logs my-container
- 进入容器交互式终端:
bash
$ docker exec -it CONTAINER [COMMAND]
例如,进入名为 "my-container" 的容器的终端:
bash
$ docker exec -it my-container /bin/bash
- 复制文件到/从容器:
bash
$ docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
$ docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
例如,将本地文件复制到名为 "my-container" 的容器中:
bash
$ docker cp my-file.txt my-container:/path/to/destination
- 暂停和恢复容器:
bash
$ docker pause CONTAINER
$ docker unpause CONTAINER
例如,暂停名为 "my-container" 的容器:
bash
$ docker pause my-container
这些是一些常用的 Docker
容器操作命令。Docker
提供了丰富的功能,可以让你轻松地管理和操作容器,以及与容器进行交互。根据具体需求,你可以使用这些命令来创建、管理和维护 Docker
容器。
仓库
Docker
仓库是用于存储、共享和管理 Docker
镜像的地方。它允许开发人员和组织将自己构建的镜像或从其他来源获取的镜像上传到中央仓库,以便其他人可以访问和使用这些镜像。以下是关于 Docker
仓库的详细信息:
-
公共 Docker 仓库:
-
Docker Hub
:Docker Hub
是最知名的公共Docker
仓库,包含了数以百万计的官方和社区维护的Docker
镜像。开发人员可以在Docker Hub
上搜索、拉取和分享容器镜像。Docker Hub
提供了免费和付费的账户,允许用户创建自己的仓库并共享镜像。 -
Docker Hub 的 URL:hub.docker.com/
-
-
私有 Docker 仓库:
-
Docker
还允许组织和企业创建私有Docker
仓库,以存储和管理内部使用的镜像。私有仓库可以在自己的服务器上搭建,也可以使用云服务提供的容器镜像存储服务。 -
私有 Docker 仓库通常用于存储敏感或专有的镜像,只有授权的用户可以访问。
-
-
Docker 仓库操作:
-
拉取镜像:使用
docker pull
命令从仓库中拉取镜像到本地。bash$ docker pull <repository_name>:<tag>
-
推送镜像:使用
docker push
命令将本地镜像推送到仓库中。bash$ docker push <repository_name>:<tag>
-
搜索镜像:使用
docker search
命令在仓库中搜索镜像。bash$ docker search <keyword>
-
登录和注销:使用
docker login
和docker logout
命令登录和注销 Docker 仓库账户。bash$ docker login $ docker logout
-
-
标签(Tags):
-
Docker
镜像可以使用标签来标识不同的版本或配置。通常,标签以<repository_name>:<tag>
的形式出现,例如nginx:latest
。 -
标签允许你指定要拉取或推送的特定版本的镜像。
-
通常,
latest
标签表示最新版本的镜像。
-
Docker
仓库是 Docker
生态系统的关键组成部分,它使得容器镜像的共享、分发和管理变得更加便捷,有助于构建、部署和运行容器化应用程序。无论是在开发、测试还是生产环境中,Docker
仓库都扮演着重要的角色。
总结
Docker
技术越来越活,容器化部署方案发展的也是如火如荼,以上只是一些简单的有关Docker
知识,Docker
原理和一些深入的知识咋们这没有做过多的讲解,像工作中比较有用的Dockerfile
多阶段构建和基于 Docker
的 CI/CD
等,本文只是为了咋们这个系列文章进行的一个入门知识介绍,深入了解还需观看官方文档。
一个来自底层的小白程序员,希望大家多多点赞 、收藏 、关注,你的鼓励是我前进的动力,谢谢大家。
温馨提示 :Docker
命令也不需要记住,使用的多了你就记住了。