为您的扩展添加后端

您的扩展可以附带一个后端部分,前端可以与其交互。本页提供了关于为什么以及如何添加后端的信息。

在开始之前,请确保您已安装最新版本的 Docker Desktop

提示

查阅 快速入门指南docker extension init <my-extension>。它们为您的扩展提供了更好的基础,因为它们更具时效性,并且与您安装的 Docker Desktop 相关。

为什么要添加后端?

得益于 Docker Extensions SDK,大多数情况下,您应该能够直接从 前端 完成 Docker CLI 所需的操作。

尽管如此,在某些情况下您可能需要为扩展添加后端。目前为止,扩展构建者已使用后端来

  • 将数据存储在本地数据库中,并通过 REST API 将其返回。
  • 存储扩展状态,例如当按钮启动一个长时间运行的进程时,这样如果您离开扩展用户界面并返回,前端可以从上次中断的地方继续。

有关扩展后端的更多信息,请参阅 架构

为扩展添加后端

如果您使用 docker extension init 命令创建扩展,您已经有一个后端设置。否则,您必须首先创建一个包含代码的 vm 目录,并更新 Dockerfile 以将其容器化。

这是一个带有后端的扩展文件夹结构

.
├── Dockerfile # (1)
├── Makefile
├── metadata.json
├── ui
    └── index.html
└── vm # (2)
    ├── go.mod
    └── main.go
  1. 包含构建后端并将其复制到扩展容器文件系统所需的一切。
  2. 包含扩展后端代码的源文件夹。

尽管您可以从空目录或 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 时,它会创建一个已经包含 Go 后端所需内容的 Dockerfile

要在安装扩展时部署 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 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 的 **容器** 视图中看到后端服务正在运行,并在需要调试时查看日志。

提示

您可能需要在 **Settings** 中启用 **Show system containers** 选项才能看到后端容器运行。有关更多信息,请参阅 显示扩展容器

打开 Docker Desktop Dashboard 并选择 **Containers** 选项卡。您应该会看到后端服务调用返回的响应。

下一步是什么?

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.