为您的扩展添加后端
您的扩展可以交付一个后端部分,前端可以与之交互。此页面提供有关为什么以及如何添加后端的信息。
在开始之前,请确保您已安装最新版本的 Docker Desktop。
提示
查看 快速入门指南 和
docker extension init <my-extension>
。它们为您的扩展提供了更好的基础,因为它与您安装的 Docker Desktop 更为最新且相关。
为什么要添加后端?
借助 Docker 扩展 SDK,大多数情况下您应该能够直接从 前端 使用 Docker CLI 执行您所需的操作。
但是,在某些情况下,您可能需要向您的扩展添加后端。到目前为止,扩展构建者已将后端用于
- 将数据存储在本地数据库中,并通过 REST API 将其返回。
- 存储扩展状态,例如,当按钮启动一个长时间运行的进程时,以便如果您从扩展用户界面导航离开并返回,前端可以从中断的地方继续。
有关扩展后端的更多信息,请参阅 体系结构。
向扩展添加后端
如果您使用 docker extension init
命令创建了您的扩展,那么您已经拥有一个后端设置。否则,您首先必须创建一个包含代码的 vm
目录,并更新 Dockerfile 以将其容器化。
这是一个包含后端的扩展文件夹结构
.
├── Dockerfile # (1)
├── Makefile
├── metadata.json
├── ui
└── index.html
└── vm # (2)
├── go.mod
└── main.go
- 包含构建后端并将后端复制到扩展容器文件系统中所需的一切。
- 包含扩展后端代码的源文件夹。
虽然您可以从空目录或 vm-ui extension
示例 开始,但强烈建议您从 docker extension init
命令开始并根据您的需要进行更改。
提示
docker extension init
生成一个 Go 后端。但是,您仍然可以使用它作为您自己的扩展的起点,并使用任何其他语言,如 Node.js、Python、Java、.Net 或任何其他语言和框架。
在本教程中,后端服务只公开一个路由,该路由返回一个表示“Hello”的 JSON 负载。
{ "Message": "Hello" }
重要
我们建议前端和后端通过套接字和 Windows 上的命名管道进行通信,而不是通过 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
注意
使用
docker extension init
时,它会创建一个Dockerfile
,其中已经包含 Go 后端所需的内容。
要部署 Go 后端以安装扩展,您首先需要配置 Dockerfile
,以便它
- 构建后端应用程序
- 将二进制文件复制到扩展的容器文件系统中
- 容器启动时,启动二进制文件以监听扩展套接字
提示
为了简化版本管理,您可以重复使用相同的镜像来构建前端、构建后端服务以及打包扩展。
# 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 中启动扩展的后端服务,您需要在 metadata.json
文件的 vm
部分配置镜像名称。
{
"vm": {
"image": "${DESKTOP_PLUGIN_IMAGE}"
},
"icon": "docker.svg",
"ui": {
...
}
}
有关 metadata.json
的 vm
部分的更多信息,请参阅元数据。
警告
不要替换
metadata.json
文件中的${DESKTOP_PLUGIN_IMAGE}
占位符。安装扩展时,将自动用正确的镜像名称替换此占位符。
从前端调用扩展后端
使用高级前端扩展示例,我们可以调用我们的扩展后端。
使用 Docker Desktop 客户端对象,然后使用 ddClient.extension.vm.service.get
从后端服务调用 /hello
路由,该路由返回响应的主体。
将 ui/src/App.tsx
文件替换为以下代码
// ui/src/App.tsx
import React, { useEffect } from 'react';
import { createDockerDesktopClient } from "@docker/extension-api-client";
//obtain docker destkop 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 仪表板的 *容器8 选项卡中看到后端服务正在运行,并在需要调试时查看日志。
提示
您可能需要在 设置 中启用 显示系统容器 选项才能看到正在运行的后端容器。有关更多信息,请参阅显示扩展容器。
打开 Docker 仪表板并选择 容器 选项卡。您应该看到显示的后端服务调用响应。