⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Créer une extension frontend avancée

Pour commencer à créer votre extension, vous avez d'abord besoin d'un répertoire avec des fichiers qui vont du code source de l'extension aux fichiers spécifiques à l'extension requis. Cette page fournit des informations sur la façon de configurer une extension avec un frontend plus avancé.

Avant de commencer, assurez-vous d'avoir installé la dernière version de Docker Desktop.

Structure de dossiers de l'extension

Le moyen le plus rapide de créer une nouvelle extension est d'exécuter docker extension init my-extension comme dans le Guide de démarrage rapide. Cela crée un nouveau répertoire my-extension qui contient une extension entièrement fonctionnelle.

Tip

La commande docker extension init génère une extension basée sur React. Mais vous pouvez toujours l'utiliser comme point de départ pour votre propre extension et utiliser n'importe quel autre framework frontend, comme Vue, Angular, Svelte, etc. ou même rester avec du Javascript vanilla.

Bien que vous puissiez partir d'un répertoire vide ou du dossier d'exemple react-extension, il est fortement recommandé de partir de la commande docker extension init et de la modifier selon vos besoins.

.
├── 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)
  1. Contient tout ce qui est requis pour construire l'extension et l'exécuter dans Docker Desktop.
  2. Dossier de haut niveau contenant le code source de votre application frontend.
  3. Les assets qui ne sont pas compilés ou générés dynamiquement sont stockés ici. Ce peuvent être des assets statiques comme des logos ou le fichier robots.txt.
  4. Le dossier src, ou source, contient tous les composants React, les fichiers CSS externes, et les assets dynamiques qui sont importés dans les fichiers de composants.
  5. L'icône qui est affichée dans le menu de gauche du Tableau de bord Docker Desktop.
  6. Un fichier qui fournit des informations sur l'extension telles que le nom, la description et la version.

Adapter le Dockerfile

Note

Lors de l'utilisation de docker extension init, cela crée un Dockerfile qui contient déjà ce qui est nécessaire pour une extension React.

Une fois l'extension créée, vous devez configurer le Dockerfile pour construire l'extension et configurer les labels qui sont utilisés pour remplir la carte de l'extension dans le Marketplace. Voici un exemple de Dockerfile pour une extension React :

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM node:18.9-alpine3.15 AS client-builder
WORKDIR /ui
# cache packages in layer
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
# install
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 ui

Note

Dans l'exemple de Dockerfile, vous pouvez voir que le label d'image com.docker.desktop.extension.icon est défini avec une URL d'icône. Le Marketplace des Extensions affiche cette icône sans installer l'extension. Le Dockerfile inclut également COPY docker.svg . pour copier un fichier d'icône à l'intérieur de l'image. Ce second fichier d'icône est utilisé pour afficher l'interface utilisateur de l'extension dans le Tableau de bord, une fois l'extension installée.

Important

Nous n'avons pas encore de Dockerfile fonctionnel pour Vue. Remplissez le formulaire et faites-nous savoir si vous souhaitez un Dockerfile pour Vue.

Important

Nous n'avons pas encore de Dockerfile fonctionnel pour Angular. Remplissez le formulaire et faites-nous savoir si vous souhaitez un Dockerfile pour Angular.

Important

Nous n'avons pas encore de Dockerfile fonctionnel pour Svelte. Remplissez le formulaire et faites-nous savoir si vous souhaitez un Dockerfile pour Svelte.

Configurer le fichier de métadonnées

Afin d'ajouter un onglet dans Docker Desktop pour votre extension, vous devez le configurer dans le fichier metadata.json à la racine de votre répertoire d'extension.

{
  "icon": "docker.svg",
  "ui": {
    "dashboard-tab": {
      "title": "UI Extension",
      "root": "/ui",
      "src": "index.html"
    }
  }
}

La propriété title est le nom de l'extension qui est affiché dans le menu de gauche du Tableau de bord Docker Desktop. La propriété root est le chemin vers l'application frontend dans le système de fichiers du conteneur de l'extension utilisé par le système pour la déployer sur l'hôte. La propriété src est le chemin vers le point d'entrée HTML de l'application frontend dans le dossier root.

Pour plus d'informations sur la section ui du metadata.json, voir Metadata.

Construire l'extension et l'installer

Maintenant que vous avez configuré l'extension, vous devez construire l'image d'extension que Docker Desktop utilisera pour l'installer.

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

Cela a construit une image taguée awesome-inc/my-extension:latest, vous pouvez exécuter docker inspect awesome-inc/my-extension:latest pour voir plus de détails à son sujet.

Finalement, vous pouvez installer l'extension et la voir apparaître dans le Tableau de bord Docker Desktop.

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

Utiliser le client des APIs d'Extension

Pour utiliser les APIs d'Extension et effectuer des actions avec Docker Desktop, l'extension doit d'abord importer la bibliothèque @docker/extension-api-client. Pour l'installer, exécutez la commande ci-dessous :

npm install @docker/extension-api-client

Puis appelez la fonction createDockerDesktopClient pour créer un objet client pour appeler les APIs d'extension.

import { createDockerDesktopClient } from '@docker/extension-api-client';

const ddClient = createDockerDesktopClient();

Lors de l'utilisation de TypeScript, vous pouvez également installer @docker/extension-api-client-types comme dépendance de développement. Cela vous fournira des définitions de types pour les APIs d'extension et l'auto-complétion dans votre IDE.

npm install @docker/extension-api-client-types --save-dev
Auto-complétion dans un IDE

Par exemple, vous pouvez utiliser la fonction docker.cli.exec pour obtenir la liste de tous les conteneurs via la commande docker ps --all et afficher le résultat dans un tableau.

Remplacez le fichier ui/src/App.tsx par le code suivant :


// ui/src/App.tsx
import React, { useEffect } from 'react';
import {
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography
} from "@mui/material";
import { createDockerDesktopClient } from "@docker/extension-api-client";

//obtain docker desktop extension client
const ddClient = createDockerDesktopClient();

export function App() {
  const [containers, setContainers] = React.useState<any[]>([]);

  useEffect(() => {
    // List all containers
    ddClient.docker.cli.exec('ps', ['--all', '--format', '"{{json .}}"']).then((result) => {
      // result.parseJsonLines() parses the output of the command into an array of objects
      setContainers(result.parseJsonLines());
    });
  }, []);

  return (
    <Stack>
      <Typography data-testid="heading" variant="h3" role="title">
        Liste des conteneurs
      </Typography>
      <Typography
      data-testid="subheading"
      variant="body1"
      color="text.secondary"
      sx={{ mt: 2 }}
    >
      Liste simple de conteneurs utilisant le SDK des Extensions Docker.
      </Typography>
      <TableContainer sx={{mt:2}}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>ID du conteneur</TableCell>
              <TableCell>Image</TableCell>
              <TableCell>Commande</TableCell>
              <TableCell>Créé</TableCell>
              <TableCell>Statut</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>
  );
}
Capture d'écran de la liste des conteneurs.
Important

Nous n'avons pas encore d'exemple pour Vue. Remplissez le formulaire et faites-nous savoir si vous souhaitez un exemple avec Vue.

Important

Nous n'avons pas encore d'exemple pour Angular. Remplissez le formulaire et faites-nous savoir si vous souhaitez un exemple avec Angular.

Important

Nous n'avons pas encore d'exemple pour Svelte. Remplissez le formulaire et faites-nous savoir si vous souhaitez un exemple avec Svelte.

Politiques appliquées pour le code frontend

Le code de l'interface utilisateur de l'extension est rendu dans une session electron séparée et n'a pas d'environnement node.js initialisé, ni d'accès direct aux APIs electron.

Ceci afin de limiter les effets de bord inattendus possibles sur l'ensemble du Tableau de bord Docker.

Le code de l'interface utilisateur de l'extension ne peut pas effectuer de tâches privilégiées, telles que faire des modifications au système, ou spawner des sous-processus, sauf en utilisant les APIs SDK fournies avec le framework d'extension. Le code de l'interface utilisateur de l'extension peut également effectuer des interactions avec Docker Desktop, telles que naviguer vers divers endroits dans le Tableau de bord, uniquement à travers les APIs SDK d'extension.

Les parties de l'interface utilisateur des extensions sont isolées les unes des autres et le code de l'interface utilisateur de l'extension s'exécute dans sa propre session pour chaque extension. Les extensions ne peuvent pas accéder aux données de session d'autres extensions.

localStorage est l'un des mécanismes de stockage web d'un navigateur. Il permet aux utilisateurs de sauvegarder des données sous forme de paires clé-valeur dans le navigateur pour une utilisation ultérieure. localStorage n'efface pas les données lorsque le navigateur (le panneau d'extension) se ferme. Cela le rend idéal pour persister des données lors de la navigation hors de l'extension vers d'autres parties de Docker Desktop.

Si votre extension utilise localStorage pour stocker des données, les autres extensions s'exécutant dans Docker Desktop ne peuvent pas accéder au stockage local de votre extension. Le stockage local de l'extension est persisté même après l'arrêt ou le redémarrage de Docker Desktop. Lorsqu'une extension est mise à niveau, son stockage local est persisté, tandis que lorsqu'elle est désinstallée, son stockage local est complètement supprimé.

Reconstruire l'extension et la mettre à jour

Puisque vous avez modifié le code de l'extension, vous devez construire à nouveau l'extension.

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

Une fois construite, vous devez la mettre à jour.

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

Maintenant vous pouvez voir le service backend s'exécuter dans l'onglet conteneurs du Tableau de bord Docker Desktop et regarder les logs quand vous avez besoin de le déboguer.

Tip

Vous pouvez activer le rechargement à chaud pour éviter d'avoir à reconstruire l'extension à chaque fois que vous faites un changement.

Et maintenant ?