Crear una extensión frontend avanzada
Para comenzar a crear tu extensión, primero necesitas un directorio con archivos que van desde el código fuente de la extensión hasta los archivos específicos requeridos para la misma. Esta página proporciona información sobre cómo configurar una extensión con un frontend más avanzado.
Antes de comenzar, asegúrate de tener instalada la última versión de Docker Desktop.
Estructura de carpetas de la extensión
La forma más rápida de crear una nueva extensión es ejecutar docker extension init mi-extension como se describe en la Guía de inicio rápido. Esto crea un nuevo directorio mi-extension que contiene una extensión completamente funcional.
TipEl comando
docker extension initgenera una extensión basada en React. Sin embargo, puedes usarlo como punto de partida para tu propia extensión y utilizar cualquier otro framework de frontend, como Vue, Angular, Svelte, etc., o incluso quedarte con JavaScript puro.
Aunque puedes comenzar desde un directorio vacío o desde la carpeta de ejemplos de react-extension, se recomienda encarecidamente que comiences con el comando docker extension init y lo modifiques según tus necesidades.
.
├── 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)- Contiene todo lo necesario para compilar la extensión y ejecutarla en Docker Desktop.
- Carpeta de alto nivel que contiene el código fuente de tu aplicación frontend.
- Los recursos que no se compilan ni se generan dinámicamente se almacenan aquí. Pueden ser recursos estáticos como logotipos o el archivo robots.txt.
- La carpeta src, o carpeta de origen, contiene todos los componentes de React, archivos CSS externos y recursos dinámicos que se importan a los archivos de los componentes.
- El icono que se muestra en el menú izquierdo del panel de control (Dashboard) de Docker Desktop.
- Un archivo que proporciona información sobre la extensión, como el nombre, la descripción y la versión.
Adaptar el Dockerfile
NoteAl utilizar
docker extension init, este crea unDockerfileque ya contiene lo necesario para una extensión de React.
Una vez creada la extensión, debes configurar el Dockerfile para compilar la extensión y definir las etiquetas (labels) que se utilizan para rellenar la ficha de la extensión en el Marketplace. Aquí tienes un ejemplo de un Dockerfile para una extensión de React:
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM node:18.9-alpine3.15 AS client-builder
WORKDIR /ui
# almacenar paquetes en caché en la capa
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
# instalar
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 uiNota
En el ejemplo del Dockerfile, puedes ver que la etiqueta de imagen
com.docker.desktop.extension.iconestá configurada con la URL de un icono. El Marketplace de extensiones muestra este icono sin instalar la extensión. El Dockerfile también incluyeCOPY docker.svg .para copiar un archivo de icono dentro de la imagen. Este segundo archivo de icono se utiliza para mostrar la UI de la extensión en el Dashboard una vez que la extensión está instalada.
ImportantAún no tenemos un Dockerfile funcional para Vue. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Vue.
ImportantAún no tenemos un Dockerfile funcional para Angular. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Angular.
ImportantAún no tenemos un Dockerfile funcional para Svelte. Completa el formulario y haznos saber si te gustaría ver un Dockerfile para Svelte.
Configurar el archivo de metadatos
Para añadir una pestaña en Docker Desktop para tu extensión, debes configurarla en el archivo metadata.json en la raíz del directorio de tu extensión.
{
"icon": "docker.svg",
"ui": {
"dashboard-tab": {
"title": "UI Extension",
"root": "/ui",
"src": "index.html"
}
}
}La propiedad title es el nombre de la extensión que se muestra en el menú izquierdo del panel de control de Docker Desktop.
La propiedad root es la ruta a la aplicación frontend en el sistema de archivos del contenedor de la extensión, utilizada por el sistema para desplegarla en el host.
La propiedad src es la ruta al punto de entrada HTML de la aplicación frontend dentro de la carpeta root.
Para obtener más información sobre la sección ui del metadata.json, consulta Metadatos.
Compilar la extensión e instalarla
Ahora que has configurado la extensión, debes compilar la imagen de la extensión que utilizará Docker Desktop para instalarla.
docker build --tag=awesome-inc/my-extension:latest .Esto compilará una imagen etiquetada como awesome-inc/my-extension:latest. Puedes ejecutar docker inspect awesome-inc/my-extension:latest para ver más detalles al respecto.
Por último, puedes instalar la extensión y ver cómo aparece en el panel de control de Docker Desktop.
docker extension install awesome-inc/my-extension:latestUtilizar el cliente de las APIs de la extensión
Para utilizar las APIs de la extensión y realizar acciones con Docker Desktop, la extensión debe importar primero la biblioteca @docker/extension-api-client. Para instalarla, ejecuta el siguiente comando:
npm install @docker/extension-api-clientLuego, llama a la función createDockerDesktopClient para crear un objeto cliente con el fin de invocar las APIs de la extensión.
import { createDockerDesktopClient } from "@docker/extension-api-client";
const ddClient = createDockerDesktopClient();Si utilizas TypeScript, también puedes instalar @docker/extension-api-client-types como una dependencia de desarrollo. Esto te proporcionará definiciones de tipo para las APIs de la extensión y autocompletado en tu IDE.
npm install @docker/extension-api-client-types --save-dev

Por ejemplo, puedes utilizar la función docker.cli.exec para obtener la lista de todos los contenedores mediante el comando docker ps --all y mostrar el resultado en una tabla.
Reemplaza el archivo ui/src/App.tsx con el siguiente código:
// ui/src/App.tsx
import React, { useEffect } from "react";
import {
Stack,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from "@mui/material";
import { createDockerDesktopClient } from "@docker/extension-api-client";
// obtener el cliente de la extensión de Docker Desktop
const ddClient = createDockerDesktopClient();
export function App() {
const [containers, setContainers] = React.useState<any[]>([]);
useEffect(() => {
// Listar todos los contenedores
ddClient.docker.cli
.exec("ps", ["--all", "--format", '"{{json .}}"'])
.then((result) => {
// result.parseJsonLines() analiza la salida del comando en un array de objetos
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>
);
}

ImportantAún no tenemos un ejemplo para Vue. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Vue.
ImportantAún no tenemos un ejemplo para Angular. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Angular.
ImportantAún no tenemos un ejemplo para Svelte. Completa el formulario y haznos saber si te gustaría ver un ejemplo con Svelte.
Políticas aplicadas al código del frontend
El código de la UI de la extensión se renderiza en una sesión de Electron separada y no tiene un entorno de Node.js inicializado, ni acceso directo a las APIs de Electron.
Esto se hace para limitar los posibles efectos secundarios inesperados en el panel de control general de Docker.
El código de la UI de la extensión no puede realizar tareas privilegiadas, como realizar cambios en el sistema o generar subprocesos, excepto mediante el uso de las APIs del SDK provistas con el framework de extensiones. El código de la UI de la extensión también puede realizar interacciones con Docker Desktop, como navegar a varios lugares en el Dashboard, únicamente a través de las APIs del SDK de la extensión.
Las partes de la UI de las extensiones están aisladas entre sí y el código de la UI de la extensión se ejecuta en su propia sesión para cada extensión. Las extensiones no pueden acceder a los datos de sesión de otras extensiones.
localStorage es uno de los mecanismos del almacenamiento web de un navegador. Permite a los usuarios guardar datos como pares clave-valor en el navegador para su uso posterior. localStorage no borra los datos cuando el navegador (el panel de la extensión) se cierra. Esto lo hace ideal para persistir datos al navegar fuera de la extensión hacia otras partes de Docker Desktop.
Si tu extensión utiliza localStorage para almacenar datos, otras extensiones que se ejecuten en Docker Desktop no podrán acceder al almacenamiento local de tu extensión. El almacenamiento local de la extensión persiste incluso después de que Docker Desktop se detenga o reinicie. Cuando se actualiza una extensión, su almacenamiento local se conserva, mientras que cuando se desinstala, su almacenamiento local se elimina por completo.
Recompilar la extensión y actualizarla
Dado que has modificado el código de la extensión, debes compilar la extensión de nuevo.
$ docker build --tag=awesome-inc/my-extension:latest .
Una vez compilada, debes actualizarla.
$ docker extension update awesome-inc/my-extension:latest
Ahora puedes ver el servicio de backend ejecutándose en la pestaña de contenedores del panel de control de Docker Desktop y revisar los registros (logs) cuando necesites depurarlo.
TipPuedes activar la recarga en caliente (hot reloading) para evitar la necesidad de recompilar la extensión cada vez que realices un cambio.
¿Qué sigue?
- Añade un backend a tu extensión.
- Aprende a probar y depurar tu extensión.
- Aprende a configurar CI para tu extensión.
- Obtén más información sobre la arquitectura.
- Para obtener más información y pautas sobre la construcción de la UI, consulta la sección de Diseño y estilos de UI.
- Si deseas configurar la autenticación de usuarios para la extensión, consulta Autenticación.