Skip to content

Commit d7f9cb3

Browse files
authored
Merge pull request #55 from docker/feature/tutorial-hello-backend
Add minimal backend extension tutorial
2 parents 32b7567 + 2ed7a73 commit d7f9cb3

File tree

8 files changed

+261
-0
lines changed

8 files changed

+261
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
## Backend minimal extension
2+
3+
This tutorial describes a minimal example running CLI commands in the backend container. You can also build extensions with a backend services running REST services (over sockets/named pipes), see the `vm-ui extension` sample.
4+
5+
## Prerequisites
6+
7+
- [Docker Desktop build with Extensions capabilities](https://github.com/docker/desktop-extension-samples/releases/)
8+
- [Docker Extensions CLI](https://github.com/docker/desktop-extension-samples/releases/)
9+
10+
## Extension folder structure
11+
12+
In the `hello-backend` folder, at the root of the repository, you can find a ready-to-go example. It represents a UI Extension built on HTML that runs a backend service. We will go through this code example in this tutorial.
13+
14+
```bash
15+
.
16+
├── Dockerfile # (1)
17+
├── Makefile
18+
├── client # (2)
19+
│ └── src
20+
│ ├── index.html
21+
│ └── script.js
22+
├── hello.sh # (3)
23+
└── metadata.json # (4)
24+
```
25+
26+
1. Contains everything required to build the extension and run it in Docker Desktop.
27+
2. The source folder that contains all your HTML, CSS and JS files. These can also be other static assets like logos, icons, etc.
28+
3. The script that will be run inside the container.
29+
4. A file that provides information about the extension such as the name, description, and version, among others.
30+
31+
## The extension's Dockerfile
32+
33+
An extension requires a `Dockerfile` to build, publish and run the extension in Docker Desktop.
34+
35+
The bare minimum configuration that a Dockerfile's extension requires to function properly is:
36+
37+
- Labels - required to provide extra information about the extension.
38+
- The src code - in this case, an `index.html` that sits within the `ui` folder.
39+
- The `metadata.json` file.
40+
- The command to run the container backend service indefinitely.
41+
42+
```Dockerfile title="Dockerfile" linenums="1"
43+
FROM alpine:3.15
44+
45+
LABEL org.opencontainers.image.title="HelloBackend" \
46+
org.opencontainers.image.description="A sample extension that runs a shell script inside a container's Desktop VM." \
47+
org.opencontainers.image.vendor="Docker Inc." \
48+
com.docker.desktop.extension.api.version="1.0.0-beta.1"
49+
50+
COPY hello.sh .
51+
COPY metadata.json .
52+
COPY client/src ./ui
53+
54+
CMD [ "sleep", "infinity" ]
55+
```
56+
57+
## Configure the Extension metadata file
58+
59+
A `metadata.json` file is required at the root of the image filesystem.
60+
61+
```json title="metadata.json" linenums="1"
62+
{
63+
"desktop-plugin-version": "1.0.0-beta.1",
64+
"name": "hello-backend",
65+
"provider": "Docker Inc.",
66+
"vm": {
67+
"image": "${DESKTOP_PLUGIN_IMAGE}"
68+
},
69+
"ui": {
70+
"dashboard-tab": {
71+
"title": "Hello Backend Extension",
72+
"root": "/ui",
73+
"src": "index.html"
74+
}
75+
}
76+
}
77+
```
78+
79+
> Do **not** replace the `${DESKTOP_PLUGIN_IMAGE}` placeholder. It will be replaced automatically when installing the extension.
80+
81+
## Build the extension
82+
83+
```bash
84+
docker build -t desktop-hello-backend-extension:0.0.1 .
85+
```
86+
87+
### Build the extension for multiple platforms
88+
89+
```bash
90+
docker buildx build --platform=linux/amd64,linux/arm64 -t desktop-hello-backend-extension:0.0.1 .
91+
```
92+
93+
## Validate the extension
94+
95+
Next, verify the extension image complies with the requisites to be a compliant Desktop Extension.
96+
97+
```bash
98+
docker extension validate desktop-hello-backend-extension:0.0.1
99+
```
100+
101+
The validation will check if the extension's `Dockerfile` specifies all the required labels and if the metadata file is valid against the JSON schema file.
102+
103+
If your extension is valid, you should see the following message:
104+
105+
`The extension image "desktop-hello-backend-extension:0.0.1" is valid`.
106+
107+
## Install the extension
108+
109+
Now that the extension is packaged as a Docker image, let's proceed with the installation. To do so, we'll use the Docker Extensions CLI.
110+
111+
> Enable Docker Desktop Extensions
112+
>
113+
> Ensure the Extensions capabilities are enabled in the Docker Desktop build by running `docker extension enable`
114+
115+
To install the extension in Docker Desktop, run:
116+
117+
```bash
118+
docker extension install desktop-hello-backend-extension:0.0.1
119+
```
120+
121+
If the installation was successful, you should see the following output:
122+
123+
```bash
124+
Installing new extension "hello-backend" with desktop-hello-backend-extension:0.0.1 ...
125+
Installing service in Desktop VM...
126+
Setting additional compose attributes
127+
VM service started
128+
Installing Desktop extension UI for tab "Hello Backend Extension"...
129+
Extension UI tab "Hello Backend Extension" added.
130+
Extension "hello-backend" installed successfully
131+
```
132+
133+
## Preview the extension
134+
135+
You can verify that the extension has been installed successfully using the following CLI command:
136+
137+
```bash
138+
docker extension ls
139+
```
140+
141+
It outputs all the extensions installed:
142+
143+
```bash
144+
PLUGIN PROVIDER IMAGE UI VM HOST
145+
hello-backend Docker Inc. desktop-hello-backend-extension:0.0.1 1 tab(Hello Backend Extension) Running(1) -
146+
```
147+
148+
To preview the extension in Docker Desktop, close and open the Docker Desktop Dashboard once the installation has completed.
149+
150+
On the left-menu, you should see a new tab with the name `Hello Backend Extension`. Click on it to load the main window that will render content of the `index.html` page.
151+
152+
![Backend Hello Extension](images/backend-minimal-extension.png)
153+
154+
## Publish the extension
155+
156+
In order to publish the extension, we have to upload the Docker image to [DockerHub](https://hub.docker.com).
157+
158+
Let's tag the previous image to preprend the account owner at the beginning of the image name:
159+
160+
```bash
161+
docker tag desktop-hello-backend-extension:0.0.1 owner/desktop-hello-backend-extension:0.0.1
162+
```
163+
164+
```bash
165+
docker push owner/desktop-hello-backend-extension:0.0.1
166+
```
167+
168+
> Note that 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`.
169+
>
170+
> See [distribution and new releases](../DISTRIBUTION.md#distribution-and-new-releases) for more information.
171+
>
172+
> See <a href="https://semver.org/" target="__blank">semver.org</a> to learn more about semantic versioning.
173+
174+
> Having trouble to push the image?
175+
>
176+
> Ensure you are logged into DockerHub. Otherwise, run `docker login` to authenticate.
177+
178+
## Clean up
179+
180+
To remove the extension run:
181+
182+
```bash
183+
docker extension rm hello-backend
184+
```
185+
186+
The following output should be displayed:
187+
188+
```bash
189+
Removing extension hello-backend...
190+
Removing extension VM service...
191+
Extension removed from Desktop VM
192+
Extension UI tab Hello Backend Extension removed
193+
Extension "hello-backend" removed
194+
```
144 KB
Loading

hello-backend/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM alpine:3.15
2+
3+
LABEL org.opencontainers.image.title="HelloBackend" \
4+
org.opencontainers.image.description="A sample extension that runs a shell script inside a container's Desktop VM." \
5+
org.opencontainers.image.vendor="Docker Inc." \
6+
com.docker.desktop.extension.api.version="1.0.0-beta.1"
7+
8+
COPY hello.sh .
9+
COPY metadata.json .
10+
COPY client/src ./ui
11+
12+
CMD [ "sleep", "infinity" ]

hello-backend/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
extension: ## Build service image to be deployed as a desktop extension
2+
docker build --tag=desktop-hello-backend-extension .
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
7+
<body class="dockerDesktopTheme">
8+
<h1>Hello Backend Extension</h1>
9+
<p>This Desktop Extension will execute a remote script inside the container in the Desktop VM. You will see the output of the script in the text area below.</p>
10+
11+
<label for="fname">Name</label>
12+
<div>
13+
<input id="input" type="text" placeholder="John"></input>
14+
<button onclick="runScript()">Submit</button>
15+
</div>
16+
17+
</br>
18+
19+
<label for="fname">Script output:</label>
20+
<div>
21+
<textarea id="textarea" disabled></textarea>
22+
</div>
23+
24+
<script type="application/javascript" src="./script.js"></script>
25+
</body>
26+
</html>

hello-backend/client/src/script.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function runScript() {
2+
const inputText = document.getElementById("input").value;
3+
4+
window.ddClient.backend
5+
.execInVMExtension(`./hello.sh ${inputText}`)
6+
.then((value) => {
7+
console.log(value);
8+
document.getElementById("textarea").innerHTML = value.stdout;
9+
});
10+
}

hello-backend/hello.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
echo "Hello, $1!"

hello-backend/metadata.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"desktop-plugin-version": "1.0.0-beta.1",
3+
"name": "hello-backend",
4+
"provider": "Docker Inc.",
5+
"vm": {
6+
"image": "${DESKTOP_PLUGIN_IMAGE}"
7+
},
8+
"ui": {
9+
"dashboard-tab": {
10+
"title": "Hello Backend Extension",
11+
"root": "/ui",
12+
"src": "index.html"
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)