Compartir comentarios
Las respuestas se generan en base a la documentación.

Añadir un backend a tu extensión

Tu extensión puede incluir una parte de backend con la que el frontend pueda interactuar. Esta página proporciona información sobre por qué y cómo añadir un backend.

Antes de comenzar, asegúrate de tener instalada la última versión de Docker Desktop.

Consejo

Consulta la Guía de inicio rápido y ejecuta docker extension init <mi-extension>. Proporcionan una mejor base para tu extensión, ya que están más actualizados y relacionados con tu instalación de Docker Desktop.

¿Por qué añadir un backend?

Gracias al SDK de extensiones de Docker, la mayoría de las veces deberías poder hacer lo que necesitas desde la CLI de Docker directamente desde el frontend.

No obstante, hay algunos casos en los que podrías necesitar añadir un backend a tu extensión. Hasta ahora, los creadores de extensiones han utilizado el backend para:

  • Almacenar datos en una base de datos local y servirlos de vuelta mediante una API REST.
  • Almacenar el estado de la extensión, por ejemplo, cuando un botón inicia un proceso de larga duración, de modo que si sales de la interfaz de usuario de la extensión y regresas, el frontend pueda continuar donde lo dejó.

Para obtener más información sobre los backends de las extensiones, consulta la Arquitectura.

Añadir un backend a la extensión

Si creaste tu extensión utilizando el comando docker extension init, ya tienes una configuración de backend. De lo contrario, primero debes crear un directorio vm que contenga el código y actualizar el Dockerfile para contenedorizarlo.

Aquí tienes la estructura de carpetas de la extensión con un backend:

.
├── Dockerfile # (1)
├── Makefile
├── metadata.json
├── ui
    └── index.html
└── vm # (2)
    ├── go.mod
    └── main.go
  1. Contiene todo lo necesario para compilar el backend y copiarlo en el sistema de archivos del contenedor de la extensión.
  2. La carpeta de origen que contiene el código de backend de la extensión.

Aunque puedes comenzar desde un directorio vacío o desde el ejemplo de vm-ui extension, se recomienda encarecidamente que comiences con el comando docker extension init y lo modifiques según tus necesidades.

Tip

El comando docker extension init genera un backend en Go. Sin embargo, puedes usarlo como punto de partida para tu propia extensión y utilizar cualquier otro lenguaje como Node.js, Python, Java, .NET o cualquier otro lenguaje y framework.

En este tutorial, el servicio de backend simplemente expone una ruta que devuelve una carga útil (payload) JSON que dice "Hello".

{ "Message": "Hello" }
Important

Recomendamos que el frontend y el backend se comuniquen a través de sockets (y tuberías con nombre en Windows) en lugar de HTTP. Esto evita colisiones de puertos con cualquier otra aplicación o contenedor en ejecución en el host. Además, algunos usuarios de Docker Desktop trabajan en entornos restringidos donde no pueden abrir puertos en sus máquinas. Al elegir el lenguaje y el framework para tu backend, asegúrate de que admita la conexión por sockets.

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
}
Important

Aún no tenemos un ejemplo funcional para Node. Completa el formulario y haznos saber si te gustaría ver un ejemplo para Node.

Important

Aún no tenemos un ejemplo funcional para Python. Completa el formulario y haznos saber si te gustaría ver un ejemplo para Python.

Important

Aún no tenemos un ejemplo funcional para Java. Completa el formulario y haznos saber si te gustaría ver un ejemplo para Java.

Important

Aún no tenemos un ejemplo funcional para .NET. Completa el formulario y haznos saber si te gustaría ver un ejemplo para .NET.

Adaptar el Dockerfile

Note

Al utilizar docker extension init, este comando crea un Dockerfile que ya contiene lo necesario para un backend en Go.

Para desplegar tu backend en Go al instalar la extensión, primero debes configurar el Dockerfile para que:

  • Compile la aplicación de backend
  • Copie el binario en el sistema de archivos del contenedor de la extensión
  • Inicie el binario cuando el contenedor arranque, escuchando en el socket de la extensión
Tip

Para facilitar la gestión de versiones, puedes reutilizar la misma imagen para construir el frontend, compilar el servicio de backend y empaquetar la extensión.

# syntax=docker/dockerfile:1
FROM node:17.7-alpine3.14 AS client-builder
# ... construir aplicación frontend

# Compilar el backend en Go
FROM golang:1.17-alpine AS builder
ENV CGO_ENABLED=0
WORKDIR /backend
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=bind,source=vm/.,target=. \
    go build -trimpath -ldflags="-s -w" -o bin/service

FROM alpine:3.15
# ... añadir etiquetas y copiar la aplicación frontend

COPY --from=builder /backend/bin/service /
CMD /service -socket /run/guest-services/extension-allthethings-extension.sock
Important

Aún no tenemos un Dockerfile funcional para Node. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Node.

Important

Aún no tenemos un Dockerfile funcional para Python. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Python.

Important

Aún no tenemos un Dockerfile funcional para Java. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Java.

Important

Aún no tenemos un Dockerfile funcional para .NET. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para .NET.

Configure the metadata file

Para iniciar el servicio de backend de tu extensión dentro de la VM de Docker Desktop, debes configurar el nombre de la imagen en la sección vm del archivo metadata.json.

{
  "vm": {
    "image": "${DESKTOP_PLUGIN_IMAGE}"
  },
  "icon": "docker.svg",
  "ui": {
    ...
  }
}

Para obtener más información sobre la sección vm del metadata.json, consulta Metadatos.

Warning

No reemplaces el marcador de posición ${DESKTOP_PLUGIN_IMAGE} en el archivo metadata.json. El marcador de posición se reemplaza automáticamente con el nombre correcto de la imagen cuando se instala la extensión.

Invocar el backend de la extensión desde tu frontend

Utilizando el ejemplo avanzado de extensión frontend, podemos invocar el backend de nuestra extensión.

Utiliza el objeto Docker Desktop Client y luego invoca la ruta /hello desde el servicio de backend con ddClient.extension.vm.service.get para obtener el cuerpo de la respuesta.

Reemplaza el archivo ui/src/App.tsx con el siguiente código:

// ui/src/App.tsx
import React, { useEffect, useState } from "react";
import { createDockerDesktopClient } from "@docker/extension-api-client";
import { Typography } from "@mui/material";

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>;
}
Important

Aún no tenemos un ejemplo para Vue. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Vue.

Important

Aún no tenemos un ejemplo para Angular. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Angular.

Important

Aún no tenemos un ejemplo para Svelte. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Svelte.

Recompilar la extensión y actualizarla

Dado que has modificado la configuración de la extensión y has añadido una etapa en el Dockerfile, debes recompilar la extensión.

docker build --tag=awesome-inc/my-extension:latest .

Una vez compilada, debes actualizarla o instalarla si aún no lo has hecho.

docker extension update awesome-inc/my-extension:latest

Ahora puedes ver el servicio de backend ejecutándose en la vista Containers (Contenedores) del panel de control de Docker Desktop y revisar los registros (logs) cuando necesites depurarlo.

Tip

Es posible que debas activar la opción Show system containers (Mostrar contenedores del sistema) en Settings (Configuración) para ver el contenedor del backend ejecutándose. Consulta Mostrar contenedores de la extensión para obtener más información.

Abre el panel de control de Docker Desktop y selecciona la pestaña Containers (Contenedores). Deberías ver en pantalla la respuesta de la llamada al servicio de backend.

¿Qué sigue?