Signed-off-by: khs1994 <khs1994@khs1994.com>pull/398/head
parent
d3c197ddfc
commit
0370871867
|
@ -1,7 +1,8 @@
|
|||
language: bash
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- openssl aes-256-cbc -K $encrypted_6cc8cff04075_key -iv $encrypted_6cc8cff04075_iv
|
||||
-in .travis/id_rsa.enc -out ~/.ssh/id_rsa -d
|
||||
|
@ -10,8 +11,10 @@ before_install:
|
|||
- date
|
||||
- git config --global user.name "khs1994"
|
||||
- git config --global user.email "khs1994@khs1994.com"
|
||||
|
||||
script:
|
||||
- docker run -it --rm -v $PWD:/srv/gitbook-src yeasy/docker_practice build
|
||||
|
||||
after_success:
|
||||
- sudo chmod -R 777 _book
|
||||
- echo "FROM nginx:1.13.8-alpine" >> Dockerfile
|
||||
|
@ -29,14 +32,17 @@ after_success:
|
|||
- COMMIT=`date "+%F %T"`
|
||||
- git commit -m "Travis CI Site updated $COMMIT"
|
||||
- git push -f origin master:"$DEPLOY_BRANCH"
|
||||
|
||||
env:
|
||||
global:
|
||||
- DEPLOY_BRANCH: pages
|
||||
# - DEPLOY_BRANCH: legacy-pages
|
||||
- REPO: git@github.com:yeasy/docker_practice.git
|
||||
|
||||
addons:
|
||||
ssh_known_hosts:
|
||||
- github.com
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
## 主要修订记录
|
||||
|
||||
* 1.1.0 2019-06-30
|
||||
* 增加 `BuildKit`
|
||||
* 增加 `docker manifest` 命令使用说明
|
||||
|
||||
* 1.0.0: 2018-12-31
|
||||
* 全面支持 v18.x 新版本
|
||||
* 添加如何调试 Docker
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v18.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)](https://u.jd.com/tKZmVG)
|
||||
|
||||
**v1.0.0**
|
||||
**v1.1.0**
|
||||
|
||||
[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!
|
||||
|
||||
|
@ -40,7 +40,7 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初
|
|||
* QQ 群 VII (已满):252403484
|
||||
* QQ 群 VIII(已满):544818750
|
||||
* QQ 群 IX (已满):571502246
|
||||
* QQ 群 X (可加):145983035
|
||||
* QQ 群 X (可加):145983035
|
||||
|
||||
>如果有问题,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
* [参考文档](image/dockerfile/references.md)
|
||||
* [Dockerfile 多阶段构建](image/multistage-builds/README.md)
|
||||
* [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md)
|
||||
* [构建多种系统架构支持的 Docker 镜像](image/manifest.md)
|
||||
* [使用 BuildKit 构建镜像](image/buildkit.md)
|
||||
* [其它制作镜像的方式](image/other.md)
|
||||
* [实现原理](image/internal.md)
|
||||
* [操作容器](container/README.md)
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
## 使用 `BuildKit` 构建镜像
|
||||
|
||||
**BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。
|
||||
|
||||
**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(Docker Hub 自动构建、腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)**
|
||||
|
||||
**注意:docker-compose build 命令暂时不支持 BuildKit**
|
||||
|
||||
下面介绍如何在 Docker CE 18.09+ 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。
|
||||
|
||||
### 启用 `BuildKit`
|
||||
|
||||
启用 `BuildKit` 必须先设置 **环境变量**。
|
||||
|
||||
Linux、macOS 执行如下命令:
|
||||
|
||||
```bash
|
||||
$ export DOCKER_BUILDKIT=1
|
||||
```
|
||||
|
||||
Windows 执行如下命令:
|
||||
|
||||
```powershell
|
||||
$ set $env:DOCKER_BUILDKIT=1
|
||||
```
|
||||
|
||||
> 以上是设置环境变量的临时方法,若使环境变量永久生效请读者自行设置。
|
||||
|
||||
### `Dockerfile` 新增指令详解
|
||||
|
||||
启用 `BuildKit` 之后,我们可以使用下面几个新的指令来加快镜像构建。
|
||||
|
||||
#### `RUN --mount=type=cache`
|
||||
|
||||
目前,几乎所有的程序都会使用依赖管理工具,例如 `Go` 中的 `go mod`、`Node.js` 中的 `npm` 等等,当我们构建一个镜像时,往往会重复的从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。
|
||||
|
||||
例如一个前端工程需要用到 `npm`:
|
||||
|
||||
```docker
|
||||
FROM node:alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
RUN npm i --registry=https://registry.npm.taobao.org \
|
||||
&& rm -rf ~/.npm
|
||||
|
||||
COPY src /app/src
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
```
|
||||
|
||||
使用多阶段构建,构建的镜像中只包含了目标文件夹 `dist`,但仍然存在一些问题,当 `package.json` 文件变动时,`RUN npm i && rm -rf ~/.npm` 这一层会重新执行,变更多次后,生成了大量的中间层镜像。
|
||||
|
||||
为解决这个问题,进一步的我们可以设想一个类似 **数据卷** 的功能,在镜像构建时把 `node_modules` 文件夹挂载上去,在构建完成后,这个 `node_modules` 文件夹会自动卸载,实际的镜像中并不包含 `node_modules` 这个文件夹,这样我们就省去了每次获取依赖的时间,大大增加了镜像构建效率,同时也避免了生成了大量的中间层镜像。
|
||||
|
||||
`BuildKit` 提供了 `RUN --mount=type=cache` 指令,可以实现上边的设想。
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
FROM node:alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
|
||||
--mount=type=cache,target=/root/.npm,id=npm_cache \
|
||||
npm i --registry=https://registry.npm.taobao.org
|
||||
|
||||
COPY src /app/src
|
||||
|
||||
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
|
||||
# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \
|
||||
npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
# COPY --from=builder /app/dist /app/dist
|
||||
|
||||
# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令
|
||||
RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \
|
||||
# --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \
|
||||
mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist
|
||||
```
|
||||
|
||||
**由于 `BuildKit` 为实验特性,每个 `Dockerfile` 文件开头都必须加上如下指令**
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
```
|
||||
|
||||
第一个 `RUN` 指令执行后,`id` 为 `my_app_npm_module` 的缓存文件夹挂载到了 `/app/node_modules` 文件夹中。多次执行也不会产生多个中间层镜像。
|
||||
|
||||
第二个 `RUN` 指令执行时需要用到 `node_modules` 文件夹,`node_modules` 已经挂载,命令也可以正确执行。
|
||||
|
||||
第三个 `RUN` 指令将上一阶段产生的文件复制到指定位置,`from` 指明缓存的来源,这里 `builder` 表示缓存来源于构建的第一阶段,`source` 指明缓存来源的文件夹。
|
||||
|
||||
上面的 `Dockerfile` 中 `--mount=type=cache,...` 中指令作用如下:
|
||||
|
||||
|Option |Description|
|
||||
|---------------------|-----------|
|
||||
|`id` | `id` 设置一个标志,以便区分缓存。|
|
||||
|`target` (必填项) | 缓存的挂载目标文件夹。|
|
||||
|`ro`,`readonly` | 只读,缓存文件夹不能被写入。 |
|
||||
|`sharing` | 有 `shared` `private` `locked` 值可供选择。`sharing` 设置当一个缓存被多次使用时的表现,由于 `BuildKit` 支持并行构建,当多个步骤使用同一缓存时(同一 `id`)会发生冲突。`shared` 表示多个步骤可以同时读写,`private` 表示当多个步骤使用同一缓存时,每个步骤使用不同的缓存,`locked` 表示当一个步骤完成释放缓存后,后一个步骤才能继续使用该缓存。|
|
||||
|`from` | 缓存来源(构建阶段),不填写时为空文件夹。|
|
||||
|`source` | 来源的文件夹路径。|
|
||||
|
||||
#### `RUN --mount=type=bind`
|
||||
|
||||
该指令可以将一个镜像(或上一构建阶段)的文件挂载到指定位置。
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoint,target=/docker-php-entrypoint \
|
||||
cat /docker-php-entrypoint
|
||||
```
|
||||
|
||||
#### `RUN --mount=type=tmpfs`
|
||||
|
||||
该指令可以将一个 `tmpfs` 文件系统挂载到指定位置。
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
RUN --mount=type=tmpfs,target=/temp \
|
||||
mount | grep /temp
|
||||
```
|
||||
|
||||
#### `RUN --mount=type=secret`
|
||||
|
||||
该指令可以将一个文件挂载到指定位置。
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
|
||||
cat /root/.aws/credentials
|
||||
```
|
||||
|
||||
```bash
|
||||
$ docker build -t test --secret id=aws,src=$HOME/.aws/credentials .
|
||||
```
|
||||
|
||||
#### `RUN --mount=type=ssh`
|
||||
|
||||
该指令可以挂载 `ssh` 密钥。
|
||||
|
||||
```docker
|
||||
# syntax = docker/dockerfile:experimental
|
||||
FROM alpine
|
||||
RUN apk add --no-cache openssh-client
|
||||
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
|
||||
RUN --mount=type=ssh ssh git@gitlab.com | tee /hello
|
||||
```
|
||||
|
||||
```bash
|
||||
$ eval $(ssh-agent)
|
||||
$ ssh-add ~/.ssh/id_rsa
|
||||
(Input your passphrase here)
|
||||
$ docker build -t test --ssh default=$SSH_AUTH_SOCK .
|
||||
```
|
||||
|
||||
### 清理构建缓存
|
||||
|
||||
执行以下命令清理构建缓存
|
||||
|
||||
```bash
|
||||
$ docker builder prune
|
||||
```
|
||||
|
||||
### 官方文档
|
||||
|
||||
* https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
|
|
@ -1,13 +0,0 @@
|
|||
## BuildKit
|
||||
|
||||
BuildKit 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。
|
||||
|
||||
下面介绍如何在 Docker CE 18.09+ 版本中使用 BuildKit 构建 Docker 镜像。
|
||||
|
||||
```bash
|
||||
$ export DOCKER_BUILDKIT=1
|
||||
|
||||
# Windows
|
||||
|
||||
$ set $env:DOCKER_BUILDKIT=1
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
FROM node:alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
RUN npm i --registry=https://registry.npm.taobao.org \
|
||||
&& rm -rf ~/.npm
|
||||
|
||||
COPY src /app/src
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
|
@ -0,0 +1,37 @@
|
|||
# syntax = docker/dockerfile:experimental
|
||||
|
||||
FROM node:alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
|
||||
--mount=type=cache,target=/root/.npm,id=npm_cache \
|
||||
npm i --registry=https://registry.npm.taobao.org
|
||||
|
||||
COPY src /app/src
|
||||
|
||||
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
|
||||
# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \
|
||||
npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
# COPY --from=builder /app/dist /app/dist
|
||||
|
||||
# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令
|
||||
RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \
|
||||
# --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \
|
||||
mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist
|
||||
|
||||
RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoint,target=/docker-php-entrypoint \
|
||||
cat /docker-php-entrypoint
|
||||
|
||||
RUN --mount=type=tmpfs,target=/temp \
|
||||
mount | grep /temp
|
||||
|
||||
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
|
||||
cat /root/.aws/credentials
|
||||
|
||||
# docker build -t test --secret id=aws,src=$PWD/aws.txt --progress=plain -f Dockerfile.buildkit .
|
|
@ -0,0 +1 @@
|
|||
awskey
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "my_app",
|
||||
"version": "19.6.0",
|
||||
"devDependencies": {
|
||||
"webpack": "*",
|
||||
"webpack-cli": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "mkdir -p $PWD/dist && cp -r src/* dist/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
console.log(1);
|
|
@ -0,0 +1,178 @@
|
|||
## 构建多种系统架构支持的 Docker 镜像 -- docker manifest 命令详解
|
||||
|
||||
我们知道使用镜像创建一个容器,该镜像必须与 Docker 宿主机系统架构一致,例如 `Linux x86_64` 架构的系统中只能使用 `Linux x86_64` 的镜像创建容器。
|
||||
|
||||
> macOS 除外,其使用了 [binfmt_misc](https://docs.docker.com/docker-for-mac/multi-arch/) 提供了多种架构支持,在 macOS 系统上 (x86_64) 可以运行 arm 等其他架构的镜像。
|
||||
|
||||
例如我们在 `Linux x86_64` 中构建一个 `username/test` 镜像。
|
||||
|
||||
```Dockerfile
|
||||
FROM alpine
|
||||
|
||||
CMD echo 1
|
||||
```
|
||||
|
||||
构建镜像后推送到 Docker Hub,之后我们尝试在树莓派 `Linux arm64v8` 中使用这个镜像。
|
||||
|
||||
```bash
|
||||
$ docker run -it --rm username/test
|
||||
```
|
||||
|
||||
可以发现这个镜像根本获取不到。
|
||||
|
||||
要解决这个问题,通常采用的做法是通过镜像名区分不同系统架构的镜像,例如在 `Linux x86_64` 和 `Linux arm64v8` 分别构建 `username/test` 和 `username/arm64v8-test` 镜像。运行时使用对应架构的镜像即可。
|
||||
|
||||
这样做显得很繁琐,那么有没有一种方法让 Docker 引擎根据系统架构自动拉取对应的镜像呢?
|
||||
|
||||
我们发现在 `Linux x86_64` 和 `Linux arm64v8` 架构的计算机中执行 `$ docker run golang:alpine go version` 时我们发现可以正确的运行。
|
||||
|
||||
这是什么原因呢?
|
||||
|
||||
原因就是 `golang:alpine` 官方镜像有一个 [`manifest` 列表](https://docs.docker.com/registry/spec/manifest-v2-2/)。
|
||||
|
||||
当用户获取一个镜像时,Docker 引擎会首先查找该镜像是否有 `manifest` 列表,如果有的话 Docker 引擎会按照 Docker 运行环境(系统及架构)查找出对应镜像(例如 `golang:alpine`)。如果没有的话会直接获取镜像(例如上例中我们构建的 `username/test`)。
|
||||
|
||||
我们可以使用 `$ docker manifest inspect golang:alpine` 查看这个 `manifest` 列表的结构。
|
||||
|
||||
由于该命令属于实验特性,必须设置如下 **环境变量** 之后才能使用:
|
||||
|
||||
```bash
|
||||
# Linux、macOS
|
||||
|
||||
$ export DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
|
||||
# Windows
|
||||
|
||||
$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
```
|
||||
|
||||
> 以上是设置环境变量的临时方法,若使环境变量永久生效请读者自行设置。
|
||||
|
||||
设置之后,执行结果如下
|
||||
|
||||
```bash
|
||||
$ docker manifest inspect golang:alpine
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:5e28ac423243b187f464d635bcfe1e909f4a31c6c8bce51d0db0a1062bec9e16",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:2945c46e26c9787da884b4065d1de64cf93a3b81ead1b949843dda1fcd458bae",
|
||||
"platform": {
|
||||
"architecture": "arm",
|
||||
"os": "linux",
|
||||
"variant": "v7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:87fff60114fd3402d0c1a7ddf1eea1ded658f171749b57dc782fd33ee2d47b2d",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"os": "linux",
|
||||
"variant": "v8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:607b43f1d91144f82a9433764e85eb3ccf83f73569552a49bc9788c31b4338de",
|
||||
"platform": {
|
||||
"architecture": "386",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:25ead0e21ed5e246ce31e274b98c09aaf548606788ef28eaf375dc8525064314",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1365,
|
||||
"digest": "sha256:69f5907fa93ea591175b2c688673775378ed861eeb687776669a48692bb9754d",
|
||||
"platform": {
|
||||
"architecture": "s390x",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
可以看出 `manifest` 列表中包含了不同系统架构所对应的镜像 `digest` 值,这样 Docker 就可以在不同的架构中使用相同的 `manifest` (例如 `golang:alpine`) 获取对应的镜像。
|
||||
|
||||
下面介绍如何使用 `$ docker manifest` 命令创建并推送 `manifest` 列表到 Docker Hub。
|
||||
|
||||
### 构建镜像
|
||||
|
||||
首先在 `Linux x86_64` 构建 `username/x8664-test` 镜像。并在 `Linux arm64v8` 中构建 `username/arm64v8-test` 镜像,构建好之后推送到 Docker Hub。
|
||||
|
||||
### 创建 `manifest` 列表
|
||||
|
||||
```bash
|
||||
# $ docker manifest create MANIFEST_LIST MANIFEST [MANIFEST...]
|
||||
$ docker manifest create username/test \
|
||||
username/x8664-test \
|
||||
username/arm64v8-test
|
||||
```
|
||||
|
||||
当要修改一个 `manifest` 列表时,可以加入 `-a,--amend` 参数。
|
||||
|
||||
### 设置 `manifest` 列表
|
||||
|
||||
```bash
|
||||
# $ docker manifest annotate [OPTIONS] MANIFEST_LIST MANIFEST
|
||||
$ docker manifest annotate username/test \
|
||||
username/x8664-test \
|
||||
--os linux --arch x86_64
|
||||
|
||||
$ docker manifest annotate username/test \
|
||||
username/arm64v8-test \
|
||||
--os linux --arch arm64 --variant v8
|
||||
```
|
||||
|
||||
这样就配置好了 `manifest` 列表。
|
||||
|
||||
### 查看 `manifest` 列表
|
||||
|
||||
```bash
|
||||
$ docker manifest inspect username/test
|
||||
```
|
||||
|
||||
### 推送 `manifest` 列表
|
||||
|
||||
最后我们可以将其推送到 Docker Hub。
|
||||
|
||||
```bash
|
||||
$ docker manifest push username/test
|
||||
```
|
||||
|
||||
### 测试
|
||||
|
||||
我们在 `Linux x86_64` `Linux arm64v8` 中分别执行 `$ docker run -it --rm username/test` 命令,发现可以正确的执行。
|
||||
|
||||
### 官方博客
|
||||
|
||||
详细了解 `manifest` 可以阅读官方博客。
|
||||
|
||||
* https://blog.docker.com/2017/11/multi-arch-all-the-things/
|
Loading…
Reference in New Issue