title | description | keywords |
---|---|---|
Minimal backend extension tutorial |
Minimal backend extension tutorial |
Docker, extensions, sdk, tutorial |
Learn how to create a simple Docker Extension that runs CLI commands in the backend.
For extensions with a backend service running REST services over sockets or named pipes, see the vm-ui extension
sample.
A Docker extension is made of several files which range from the extension's source code to the required extension-specific files.
In the minimal-backend
sample folder, you can find a ready-to-go example that represents a UI extension built on HTML that runs a backend service. We will go through this code example in this tutorial.
Although you can start from an empty directory, it is highly recommended that you start from the template below and change it accordingly to suit your needs.
.
├── Dockerfile # (1)
├── Makefile
├── client # (2)
│ └── src
│ ├── App.tsx
│ └── ... React aplication
├── hello.sh # (3)
└── metadata.json # (4)
- Contains everything required to build the extension and run it in Docker Desktop.
- The source folder that contains the UI application. In this example we use a React frontend, the main part of th extension is an App.tsx.
- The script that runs inside the container.
- A file that provides information about the extension such as the name, description, and version.
Let's reuse the React extension from the React extension tutorial, and see how we can invoke our extension backend from the App.tsx file.
Use the Docker Desktop Client object and then invoke a binary provided in our backend container (that lives inside the Docker Desktop VM) with ddClient.docker.extension.vm.cli.exec()
.
In our example, our hello.sh script returns a string as result, we obtain it with result?.stdout
.
const ddClient = createDockerDesktopClient();
const [backendInfo, setBackendInfo] = useState<string | undefined>();
async function runExtensionBackend(inputText: string) {
const result = await ddClient.extension.vm?.cli.exec("./hello.sh", [
inputText,
]);
setBackendInfo(result?.stdout);
}
An extension requires a Dockerfile
to build, publish, and run the extension in Docker Desktop.
At minimum, your Dockerfile needs:
- Labels which provide extra information about the extension.
- The source code which in this case is an
index.html
that sits within theui
folder.index.html
refers to javascript code inscript.js
. - The
metadata.json
file.
FROM node:17.7-alpine3.14 AS client-builder
# ... build React application
FROM alpine:3.15
LABEL org.opencontainers.image.title="HelloBackend" \
org.opencontainers.image.description="A sample extension that runs a shell script inside a container's Desktop VM." \
org.opencontainers.image.vendor="Docker Inc." \
com.docker.desktop.extension.api.version="1.0.0-beta.1" \
com.docker.desktop.extension.icon="https://www.docker.com/wp-content/uploads/2022/03/Moby-logo.png"
COPY hello.sh .
COPY metadata.json .
COPY --from=client-builder /app/client/dist ui
CMD [ "sleep", "infinity" ]
A metadata.json
file is required at the root of the image filesystem.
{
"vm": {
"image": "${DESKTOP_PLUGIN_IMAGE}"
},
"ui": {
"dashboard-tab": {
"title": "Hello Backend Extension",
"root": "/ui",
"src": "index.html"
}
}
}
Do not replace the
${DESKTOP_PLUGIN_IMAGE}
placeholder in themetadata.json
file. The placeholder is replaced automatically with the correct image name when the extension is installed.
To build the extension, run:
docker build -t desktop-backend-minimal-extension:0.0.1 .
To build the extension for multiple platforms, run:
docker buildx build --platform=linux/amd64,linux/arm64 -t desktop-backend-minimal-extension:0.0.1 .
Verify the extension image is compliant.
The validation checks if the extension's Dockerfile
specifies all the required labels and if the metadata file is valid against the JSON schema file.
docker extension validate desktop-backend-minimal-extension:0.0.1
If your extension is valid, the message below displays:
The extension image "desktop-backend-minimal-extension:0.0.1" is valid
.
To install the extension in Docker Desktop, run:
docker extension install desktop-backend-minimal-extension:0.0.1
If the installation is successful, the output below displays:
Installing new extension "hello-backend" with desktop-backend-minimal-extension:0.0.1 ...
Installing service in Desktop VM...
Setting additional compose attributes
VM service started
Installing Desktop extension UI for tab "Hello Backend Extension"...
Extension UI tab "Hello Backend Extension" added.
Extension "hello-backend" installed successfully
You can also enter the command below to verify the extension installed successfully:
docker extension ls
It outputs all the extensions installed:
PLUGIN PROVIDER IMAGE UI VM HOST
hello-backend Docker Inc. desktop-backend-minimal-extension:0.0.1 1 tab(Hello Backend Extension) Running(1) -
To preview the extension in Docker Desktop, close and open the Docker Desktop dashboard once the installation has completed.
The left-hand menu displays a new tab with name Hello Backend Extension
. When you select the new tab, the result below is rendered.
To publish the extension, upload the Docker image to DockerHub.
Tag the previous image to prepend the account owner at the beginning of the image name:
docker tag desktop-backend-minimal-extension:0.0.1 owner/desktop-backend-minimal-extension:0.0.1
Push the image to DockerHub:
docker push owner/desktop-backend-minimal-extension:0.0.1
Publishing extensions in the marketplace
For Docker Extensions images to be listed in Docker Desktop, they must be approved by Docker and be tagged following semantic versioning, e.g:
0.0.1
.See distribution and new releases for more information.
See semver.org to learn more about semantic versioning.
Having trouble to push the image?
Ensure you are logged into DockerHub. Otherwise, run
docker login
to authenticate.
To remove the extension, run:
docker extension rm hello-backend
The following output displays:
Removing extension hello-backend...
Removing extension VM service...
Extension removed from Desktop VM
Extension UI tab Hello Backend Extension removed
Extension "hello-backend" removed