创建高级前端扩展
要开始创建您的扩展,您首先需要一个包含从扩展源代码到所需扩展特定文件的目录。本页提供有关如何设置具有更高级前端的扩展的信息。
在开始之前,请确保您已安装最新版本的 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 或源文件夹包含所有 React 组件、外部 CSS 文件以及引入组件文件的动态资产。
- 显示在 Docker Desktop 仪表板左侧菜单中的图标。
- 一个提供扩展信息的文件,例如名称、描述和版本。
调整 Dockerfile
注意使用
docker extension init时,它会创建一个Dockerfile,其中已包含 React 扩展所需的内容。
创建扩展后,您需要配置 Dockerfile 来构建扩展并配置用于填充市场中扩展卡片的标签。以下是 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://www.docker.com/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。扩展市场在不安装扩展的情况下显示此图标。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 属性是 root 文件夹中前端应用程序 HTML 入口点的路径。
有关 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使用扩展 API 客户端
要使用扩展 API 并使用 Docker Desktop 执行操作,扩展必须首先导入 @docker/extension-api-client 库。要安装它,请运行以下命令
npm install @docker/extension-api-client然后调用 createDockerDesktopClient 函数创建一个客户端对象来调用扩展 API。
import { createDockerDesktopClient } from '@docker/extension-api-client';
const ddClient = createDockerDesktopClient();使用 TypeScript 时,您还可以将 @docker/extension-api-client-types 作为开发依赖项安装。这将为您提供扩展 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 仪表板可能产生的意外副作用。
扩展 UI 代码不能执行特权任务,例如更改系统或生成子进程,除非使用扩展框架提供的 SDK API。扩展 UI 代码还可以与 Docker Desktop 进行交互,例如导航到仪表板中的各种位置,只能通过扩展 SDK API。
扩展 UI 部分相互隔离,并且每个扩展的 UI 代码都在自己的会话中运行。扩展无法访问其他扩展的会话数据。
localStorage 是浏览器 Web 存储机制之一。它允许用户以键值对的形式将数据保存在浏览器中以供以后使用。当浏览器(扩展窗格)关闭时,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 仪表板的容器选项卡中看到后端服务正在运行,并在需要调试时查看日志。
提示您可以打开热重载,以避免每次更改都需要重新构建扩展。
下一步是什么?
- 为您的扩展添加后端。
- 了解如何测试和调试您的扩展。
- 了解如何为您的扩展设置 CI。
- 了解有关扩展架构的更多信息。
- 有关构建 UI 的更多信息和指南,请参阅设计和 UI 样式部分。
- 如果您想为扩展设置用户身份验证,请参阅身份验证。