向扩展添加后端
您的扩展可以附带一个后端部分,前端可以与之交互。本页提供了有关添加后端的原因和方法的信息。
在开始之前,请确保您已安装最新版本的 Docker Desktop。
提示
查看快速入门指南和 。它们为您的扩展提供了更好的基础,因为它是最新的,并且与您的 Docker Desktop 安装相关。
docker extension init <my-extension>
为什么要添加后端?
多亏了 Docker Extensions SDK,大多数时候您应该能够从 Docker CLI 执行所需的操作 直接从前端。
尽管如此,在某些情况下,您可能需要向扩展添加后端。到目前为止,扩展 构建者使用后端来:
- 将数据存储在本地数据库中,并使用 REST API 提供数据。
- 存储扩展状态,例如当按钮启动长时间运行的进程时,这样,如果你离开扩展用户界面并返回,前端可以从中断的地方继续。
有关扩展后端的更多信息,请参阅架构。
向扩展添加后端
如果您使用该命令创建了扩展,则您已经有后端设置。否则,您必须首先创建一个包含代码的目录,并将 Dockerfile 更新为
容器化它。docker extension init
vm
以下是带有后端的扩展文件夹结构:
.
├── Dockerfile # (1)
├── Makefile
├── metadata.json
├── ui
└── index.html
└── vm # (2)
├── go.mod
└── main.go
- 包含构建后端并将其复制到扩展的容器文件系统中所需的一切。
- 包含扩展后端代码的源文件夹。
尽管您可以从空目录或示例开始,
强烈建议您从 Command 开始,然后根据需要进行更改。vm-ui extension
docker extension init
提示
这会生成一个 Go 后端。但您仍然可以将其用作 您自己的扩展,并使用任何其他语言,如 Node.js、Python、Java、.Net 或任何其他语言和框架。
docker extension init
在本教程中,后端服务只公开一个路由,该路由返回一个显示“Hello”的 JSON 有效负载。
{ "Message": "Hello" }
重要
我们建议前端和后端通过 sockets 和 Windows 上的命名管道进行通信,而不是 HTTP 的 HTTP 请求。这可以防止与任何其他正在运行的应用程序或正在运行的容器发生端口冲突 在主机上。此外,一些 Docker Desktop 用户在受限环境中运行,他们 无法打开其计算机上的端口。在为后端选择语言和框架时,请确保它 支持套接字连接。
package main
import (
"flag"
"log"
"net"
"net/http"
"os"
"github.com/labstack/echo"
"github.com/sirupsen/logrus"
)
func main() {
var socketPath string
flag.StringVar(&socketPath, "socket", "/run/guest/volumes-service.sock", "Unix domain socket to listen on")
flag.Parse()
os.RemoveAll(socketPath)
logrus.New().Infof("Starting listening on %s\n", socketPath)
router := echo.New()
router.HideBanner = true
startURL := ""
ln, err := listen(socketPath)
if err != nil {
log.Fatal(err)
}
router.Listener = ln
router.GET("/hello", hello)
log.Fatal(router.Start(startURL))
}
func listen(path string) (net.Listener, error) {
return net.Listen("unix", path)
}
func hello(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, HTTPMessageBody{Message: "hello world"})
}
type HTTPMessageBody struct {
Message string
}
重要
我们还没有 Node 的工作示例。填写表格,告诉我们您是否需要 Node 的样品。
重要
我们还没有 Python 的工作示例。填写表单,告诉我们您是否需要 Python 示例。
重要
我们还没有 Java 的工作示例。填写表单,告诉我们您是否需要 Java 示例。
重要
我们没有 .NET 的工作示例。填写表单,并告诉我们您是否需要 .NET 的示例。
适配 Dockerfile
注意
使用 时,它会创建一个已包含 Go 后端所需内容的文件。
docker extension init
Dockerfile
要在安装扩展时部署 Go 后端,您首先需要配置 ,以便它:Dockerfile
- 构建后端应用程序
- 将二进制文件复制到扩展的容器文件系统中
- 当容器开始侦听扩展套接字时启动二进制文件
提示
为了简化版本管理,您可以重用相同的镜像来构建前端,构建 backend 服务,并打包扩展。
# syntax=docker/dockerfile:1
FROM node:17.7-alpine3.14 AS client-builder
# ... build frontend application
# Build the Go backend
FROM golang:1.17-alpine AS builder
ENV CGO_ENABLED=0
WORKDIR /backend
COPY vm/go.* .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go mod download
COPY vm/. .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -trimpath -ldflags="-s -w" -o bin/service
FROM alpine:3.15
# ... add labels and copy the frontend application
COPY --from=builder /backend/bin/service /
CMD /service -socket /run/guest-services/extension-allthethings-extension.sock
重要
我们还没有适用于 Node 的工作 Dockerfile。填写表格,告诉我们您是否需要适用于 Node 的 Dockerfile。
重要
我们还没有适用于 Python 的 Dockerfile。填写表格,告诉我们您是否需要适用于 Python 的 Dockerfile。
重要
我们还没有适用于 Java 的工作 Dockerfile。填写表格,告诉我们您是否需要适用于 Java 的 Dockerfile。
重要
我们没有适用于 .NET 的工作 Dockerfile。填写表单,并告诉我们您是否需要适用于 .Net 的 Dockerfile。
配置元数据文件
要在 Docker Desktop 的 VM 中启动扩展的后端服务,您必须配置镜像名称
在文件的部分中。vm
metadata.json
{
"vm": {
"image": "${DESKTOP_PLUGIN_IMAGE}"
},
"icon": "docker.svg",
"ui": {
...
}
}
有关 部分的更多信息,请参阅 元数据.vm
metadata.json
警告
不要替换文件中的占位符。安装扩展后,占位符会自动替换为正确的镜像名称。
${DESKTOP_PLUGIN_IMAGE}
metadata.json
从前端调用扩展后端
使用高级前端扩展示例,我们可以调用我们的扩展后端。
使用 Docker Desktop Client 对象,然后从后端服务调用路由,该路由将返回响应的正文。/hello
ddClient. extension.vm.service.get
将文件替换为以下代码:ui/src/App.tsx
// ui/src/App.tsx
import React, { useEffect } from 'react';
import { createDockerDesktopClient } from "@docker/extension-api-client";
//obtain docker desktop extension client
const ddClient = createDockerDesktopClient();
export function App() {
const ddClient = createDockerDesktopClient();
const [hello, setHello] = useState<string>();
useEffect(() => {
const getHello = async () => {
const result = await ddClient.extension.vm?.service?.get('/hello');
setHello(JSON.stringify(result));
}
getHello()
}, []);
return (
<Typography>{hello}</Typography>
);
}
重要
我们还没有 Vue 的示例。填写表格,告诉我们您是否需要 Vue 的示例。
重要
我们还没有 Angular 的示例。填写表格,告诉我们您是否需要 Angular 的示例。
重要
我们还没有 Svelte 的示例。填写表格,告诉我们您是否需要 Svelte 的样品。
重新构建扩展并更新
由于您已经修改了扩展的配置并在 Dockerfile 中添加了一个阶段,因此您必须重新构建扩展。
docker build --tag=awesome-inc/my-extension:latest .
构建完成后,您需要更新它,或者安装它(如果尚未安装)。
docker extension update awesome-inc/my-extension:latest
现在,您可以在 Docker Desktop Dashboard 的 Containers 视图中看到正在运行的后端服务,并在需要调试时查看日志。
提示
您可能需要在 Settings (设置) 中打开 Show system containers (显示系统容器) 选项才能看到后端容器正在运行。 有关更多信息,请参阅显示扩展容器。
打开 Docker Desktop 仪表板,然后选择 Containers 选项卡。您应该会看到来自后端服务的响应 显示呼叫。