创建一个高级前端扩展
要开始创建扩展,首先需要一个包含从扩展源代码到所需扩展特定文件的目录。本页提供有关如何设置具有更高级前端的扩展的信息。
在开始之前,请确保您已安装最新版本的 Docker Desktop。
扩展文件夹结构
创建新扩展的最快方法是运行 docker extension init my-extension
命令,就像在快速入门中所述。这会创建一个包含功能齐全的扩展的新目录 my-extension
。
提示
docker extension init
命令生成基于 React 的扩展。但您仍然可以将其作为自己扩展的起点,并使用任何其他前端框架,如 Vue、Angular、Svelte 等,甚至只使用原生 Javascript。
虽然您可以从空目录或 react-extension
示例文件夹开始,但强烈建议您从 docker extension init
命令开始,然后根据您的需求进行修改。
.
├── Dockerfile # (1)
├── ui # (2)
│ ├── public # (3)
│ │ └── index.html
│ ├── src # (4)
│ │ ├── App.tsx
│ │ ├── index.tsx
│ ├── package.json
│ └── package-lock.lock
│ ├── tsconfig.json
├── docker.svg # (5)
└── metadata.json # (6)
- 包含构建扩展并在 Docker Desktop 中运行所需的一切。
- 包含前端应用源代码的高层文件夹。
- 未编译或动态生成的资产存储在此处。这些可以是静态资产,如徽标或 robots.txt 文件。
- src 或 source 文件夹包含所有 React 组件、外部 CSS 文件以及引入组件文件中的动态资产。
- 显示在 Docker Desktop 仪表板左侧菜单中的图标。
- 提供有关扩展信息的文件,例如名称、描述和版本。
修改 Dockerfile
注意
使用
docker extension init
命令时,它会创建一个Dockerfile
,其中已包含 React 扩展所需的内容。
创建扩展后,您需要配置 Dockerfile
以构建扩展并配置用于填充 Marketplace 中扩展卡片的标签。以下是 React 扩展的 Dockerfile
示例:
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM node:18.9-alpine3.15 AS client-builder
WORKDIR /ui
# cache packages in layer
COPY ui/package.json /ui/package.json
COPY ui/package-lock.json /ui/package-lock.json
RUN --mount=type=cache,target=/usr/src/app/.npm \
npm set cache /usr/src/app/.npm && \
npm ci
# install
COPY ui /ui
RUN npm run build
FROM alpine
LABEL org.opencontainers.image.title="My extension" \
org.opencontainers.image.description="Your Desktop Extension Description" \
org.opencontainers.image.vendor="Awesome Inc." \
com.docker.desktop.extension.api.version="0.3.3" \
com.docker.desktop.extension.icon="https://docker.net.cn/wp-content/uploads/2022/03/Moby-logo.png" \
com.docker.extension.screenshots="" \
com.docker.extension.detailed-description="" \
com.docker.extension.publisher-url="" \
com.docker.extension.additional-urls="" \
com.docker.extension.changelog=""
COPY metadata.json .
COPY docker.svg .
COPY --from=client-builder /ui/build ui
注意
在示例 Dockerfile 中,您可以看到镜像标签
com.docker.desktop.extension.icon
设置为图标 URL。Extensions Marketplace 无需安装扩展即可显示此图标。Dockerfile 中还包含COPY docker.svg .
用于将一个图标文件复制到镜像内部。安装扩展后,第二个图标文件用于在仪表板中显示扩展 UI。
重要
我们还没有适用于 Vue 的工作 Dockerfile。填写此表单,告诉我们您是否想要一个适用于 Vue 的 Dockerfile。
重要
我们还没有适用于 Angular 的工作 Dockerfile。填写此表单,告诉我们您是否想要一个适用于 Angular 的 Dockerfile。
重要
我们还没有适用于 Svelte 的工作 Dockerfile。填写此表单,告诉我们您是否想要一个适用于 Svelte 的 Dockerfile。
配置元数据文件
为了在 Docker Desktop 中为您的扩展添加一个选项卡,您需要在扩展目录根目录下的 metadata.json
文件中进行配置。
{
"icon": "docker.svg",
"ui": {
"dashboard-tab": {
"title": "UI Extension",
"root": "/ui",
"src": "index.html"
}
}
}
title
属性是显示在 Docker Desktop 仪表板左侧菜单中的扩展名称。root
属性是前端应用在扩展容器文件系统中的路径,系统会使用此路径将其部署到主机上。src
属性是前端应用 HTML 入口文件在 root
文件夹内的路径。
有关 metadata.json
文件中 ui
部分的更多信息,请参阅元数据。
构建扩展并安装
现在您已经配置好了扩展,需要构建 Docker Desktop 用于安装扩展的镜像。
docker build --tag=awesome-inc/my-extension:latest .
这将构建一个标记为 awesome-inc/my-extension:latest
的镜像,您可以运行 docker inspect awesome-inc/my-extension:latest
查看更多详细信息。
最后,您可以安装扩展并在 Docker Desktop 仪表板中看到它出现。
docker extension install awesome-inc/my-extension:latest
使用 Extension API 客户端
要使用 Extension API 并与 Docker Desktop 交互,扩展必须首先导入 @docker/extension-api-client
库。要安装它,运行以下命令:
npm install @docker/extension-api-client
然后调用 createDockerDesktopClient
函数创建一个客户端对象来调用 Extension API。
import { createDockerDesktopClient } from '@docker/extension-api-client';
const ddClient = createDockerDesktopClient();
使用 Typescript 时,您还可以将 @docker/extension-api-client-types
作为开发依赖 (dev dependency) 安装。这将为您提供 Extension API 的类型定义并在 IDE 中提供自动补全功能。
npm install @docker/extension-api-client-types --save-dev


例如,您可以使用 docker.cli.exec
函数通过 docker ps --all
命令获取所有容器的列表,并将结果显示在表格中。
用以下代码替换 ui/src/App.tsx
文件内容:
// ui/src/App.tsx
import React, { useEffect } from 'react';
import {
Paper,
Stack,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography
} from "@mui/material";
import { createDockerDesktopClient } from "@docker/extension-api-client";
//obtain docker desktop extension client
const ddClient = createDockerDesktopClient();
export function App() {
const [containers, setContainers] = React.useState<any[]>([]);
useEffect(() => {
// List all containers
ddClient.docker.cli.exec('ps', ['--all', '--format', '"{{json .}}"']).then((result) => {
// result.parseJsonLines() parses the output of the command into an array of objects
setContainers(result.parseJsonLines());
});
}, []);
return (
<Stack>
<Typography data-testid="heading" variant="h3" role="title">
Container list
</Typography>
<Typography
data-testid="subheading"
variant="body1"
color="text.secondary"
sx={{ mt: 2 }}
>
Simple list of containers using Docker Extensions SDK.
</Typography>
<TableContainer sx={{mt:2}}>
<Table>
<TableHead>
<TableRow>
<TableCell>Container id</TableCell>
<TableCell>Image</TableCell>
<TableCell>Command</TableCell>
<TableCell>Created</TableCell>
<TableCell>Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{containers.map((container) => (
<TableRow
key={container.ID}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell>{container.ID}</TableCell>
<TableCell>{container.Image}</TableCell>
<TableCell>{container.Command}</TableCell>
<TableCell>{container.CreatedAt}</TableCell>
<TableCell>{container.Status}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Stack>
);
}


重要
我们还没有适用于 Vue 的示例。填写此表单,告诉我们您是否想要一个 Vue 示例。
重要
我们还没有 Angular 的示例。填写表单 并告知我们您是否需要 Angular 的示例。
重要
我们还没有 Svelte 的示例。填写表单 并告知我们您是否需要 Svelte 的示例。
前端代码强制执行的策略
扩展 UI 代码在单独的 Electron 会话中渲染,并且没有初始化 node.js 环境,也无法直接访问 Electron API。
这样做是为了限制可能对整个 Docker Dashboard 造成意外的副作用。
扩展 UI 代码不能执行特权任务,例如更改系统或生成子进程,除非使用扩展框架提供的 SDK API。扩展 UI 代码还可以通过扩展 SDK API 与 Docker Desktop 进行交互,例如导航到 Dashboard 中的不同位置。
扩展的 UI 部分彼此隔离,并且每个扩展的 UI 代码都在其自己的会话中运行。扩展无法访问其他扩展的会话数据。
localStorage
是浏览器 Web Storage 的机制之一。它允许用户在浏览器中以键值对的形式保存数据以供以后使用。当浏览器(扩展面板)关闭时,localStorage
不会清除数据。这使得它非常适合在从扩展导航到 Docker Desktop 的其他部分时持久化数据。
如果您的扩展使用 localStorage
存储数据,则在 Docker Desktop 中运行的其他扩展无法访问您的扩展的本地存储。即使在 Docker Desktop 停止或重新启动后,该扩展的本地存储也会持久保留。当扩展升级时,其本地存储会持久保留,而当它被卸载时,其本地存储会完全删除。
重新构建并更新扩展
由于您修改了扩展的代码,您必须再次构建扩展。
$ docker build --tag=awesome-inc/my-extension:latest .
构建完成后,您需要更新它。
$ docker extension update awesome-inc/my-extension:latest
现在您可以在 Docker Desktop Dashboard 的容器选项卡中看到后端服务正在运行,并在需要调试时查看日志。
提示
您可以开启热重载,以免每次进行更改时都需要重新构建扩展。
下一步?
- 为您的扩展添加一个后端。
- 了解如何测试和调试您的扩展。
- 了解如何为您的扩展设置 CI。
- 了解更多关于扩展的架构。
- 有关构建 UI 的更多信息和指南,请参阅设计和 UI 样式部分。
- 如果您想为扩展设置用户认证,请参阅认证。