2016-10-14 18:30:36 -04:00
---
2016-10-20 14:12:02 -04:00
description: Develop and use a plugin with the managed plugin system
2016-11-03 17:21:33 -04:00
keywords: "API, Usage, plugins, documentation, developer"
2016-10-14 18:30:36 -04:00
---
2016-10-12 19:23:01 -04:00
2017-10-04 13:03:55 -04:00
<!-- This file is maintained within the docker/cli GitHub
2017-07-28 13:28:23 -04:00
repository at https://github.com/docker/cli/. Make all
2016-10-19 13:25:45 -04:00
pull requests against that repo. If you see this file in
another repository, consider it read-only there, as it will
periodically be overwritten by the definitive file. Pull
requests which include edits to this file in other repositories
will be rejected.
-->
2016-10-12 19:23:01 -04:00
# Docker Engine managed plugin system
2016-10-20 14:12:02 -04:00
* [Installing and using a plugin ](index.md#installing-and-using-a-plugin )
* [Developing a plugin ](index.md#developing-a-plugin )
2017-02-06 17:44:56 -05:00
* [Debugging plugins ](index.md#debugging-plugins )
2016-10-12 19:23:01 -04:00
2017-02-21 05:38:07 -05:00
Docker Engine's plugin system allows you to install, start, stop, and remove
2017-02-14 19:40:15 -05:00
plugins using Docker Engine.
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
For information about the legacy plugin system available in Docker Engine 1.12
and earlier, see [Understand legacy Docker Engine plugins ](legacy_plugins.md ).
2016-10-12 19:23:01 -04:00
2016-11-22 10:01:14 -05:00
> **Note**: Docker Engine managed plugins are currently not supported
on Windows daemons.
2016-10-20 14:12:02 -04:00
## Installing and using a plugin
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
Plugins are distributed as Docker images and can be hosted on Docker Hub or on
a private registry.
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
To install a plugin, use the `docker plugin install` command, which pulls the
2017-02-21 05:38:07 -05:00
plugin from Docker Hub or your private registry, prompts you to grant
2016-10-20 14:12:02 -04:00
permissions or capabilities if necessary, and enables the plugin.
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
To check the status of installed plugins, use the `docker plugin ls` command.
Plugins that start successfully are listed as enabled in the output.
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
After a plugin is installed, you can use it as an option for another Docker
operation, such as creating a volume.
2016-10-12 19:23:01 -04:00
2017-09-06 18:36:20 -04:00
In the following example, you install the `sshfs` plugin, verify that it is
2016-10-20 14:12:02 -04:00
enabled, and use it to create a volume.
2016-10-12 19:23:01 -04:00
2017-09-06 18:36:20 -04:00
> **Note**: This example is intended for instructional purposes only. Once the volume is created, your SSH password to the remote host will be exposed as plaintext when inspecting the volume. You should delete the volume as soon as you are done with the example.
2016-10-12 19:23:01 -04:00
1. Install the `sshfs` plugin.
```bash
2017-09-06 18:36:20 -04:00
$ docker plugin install vieux/sshfs
Plugin "vieux/sshfs" is requesting the following privileges:
- network: [host]
- capabilities: [CAP_SYS_ADMIN]
2016-10-12 19:23:01 -04:00
Do you grant the above permissions? [y/N] y
2017-09-06 18:36:20 -04:00
vieux/sshfs
2016-10-12 19:23:01 -04:00
```
2017-09-06 18:36:20 -04:00
The plugin requests 2 privileges:
2017-10-13 17:59:19 -04:00
2016-10-20 14:12:02 -04:00
- It needs access to the `host` network.
2017-09-06 18:36:20 -04:00
- It needs the `CAP_SYS_ADMIN` capability, which allows the plugin to run
2016-10-20 14:12:02 -04:00
the `mount` command.
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
2. Check that the plugin is enabled in the output of `docker plugin ls` .
2016-10-12 19:23:01 -04:00
```bash
$ docker plugin ls
2017-09-06 18:36:20 -04:00
ID NAME TAG DESCRIPTION ENABLED
69553ca1d789 vieux/sshfs latest the `sshfs` plugin true
2016-10-12 19:23:01 -04:00
```
2016-10-18 06:01:46 -04:00
3. Create a volume using the plugin.
2016-10-20 14:12:02 -04:00
This example mounts the `/remote` directory on host `1.2.3.4` into a
2017-10-13 17:59:19 -04:00
volume named `sshvolume` .
2017-02-14 19:40:15 -05:00
2017-01-09 18:24:20 -05:00
This volume can now be mounted into containers.
2016-10-12 19:23:01 -04:00
```bash
$ docker volume create \
2017-09-06 18:36:20 -04:00
-d vieux/sshfs \
--name sshvolume \
-o sshcmd=user@1.2.3.4:/remote \
-o password=$(cat file_containing_password_for_remote_host)
2016-10-12 19:23:01 -04:00
2017-09-06 18:36:20 -04:00
sshvolume
2016-10-12 19:23:01 -04:00
```
2016-10-20 14:12:02 -04:00
4. Verify that the volume was created successfully.
2016-10-12 19:23:01 -04:00
```bash
2016-10-20 14:12:02 -04:00
$ docker volume ls
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
DRIVER NAME
2017-09-06 18:36:20 -04:00
vieux/sshfs sshvolume
2016-10-12 19:23:01 -04:00
```
2017-09-06 18:36:20 -04:00
5. Start a container that uses the volume `sshvolume` .
2016-10-12 19:23:01 -04:00
```bash
2017-09-06 18:36:20 -04:00
$ docker run --rm -v sshvolume:/data busybox ls /data
< content of / remote on machine 1 . 2 . 3 . 4 >
2016-10-12 19:23:01 -04:00
```
2017-09-06 18:36:20 -04:00
6. Remove the volume `sshvolume`
2017-01-09 18:24:20 -05:00
```bash
2017-09-06 18:36:20 -04:00
docker volume rm sshvolume
2017-02-14 19:40:15 -05:00
2017-09-06 18:36:20 -04:00
sshvolume
2017-01-09 18:24:20 -05:00
```
2016-10-20 14:12:02 -04:00
To disable a plugin, use the `docker plugin disable` command. To completely
remove it, use the `docker plugin remove` command. For other available
commands and options, see the
[command line reference ](../reference/commandline/index.md ).
2016-10-12 19:23:01 -04:00
2017-01-27 17:45:06 -05:00
2016-10-20 14:12:02 -04:00
## Developing a plugin
2016-10-12 19:23:01 -04:00
2016-10-20 14:12:02 -04:00
#### The rootfs directory
The `rootfs` directory represents the root filesystem of the plugin. In this
example, it was created from a Dockerfile:
2016-10-12 19:23:01 -04:00
2016-10-25 16:39:04 -04:00
>**Note:** The `/run/docker/plugins` directory is mandatory inside of the
plugin's filesystem for docker to communicate with the plugin.
2016-10-12 19:23:01 -04:00
```bash
$ git clone https://github.com/vieux/docker-volume-sshfs
$ cd docker-volume-sshfs
2016-12-12 18:05:53 -05:00
$ docker build -t rootfsimage .
$ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created
$ sudo mkdir -p myplugin/rootfs
$ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs
2016-10-12 19:23:01 -04:00
$ docker rm -vf "$id"
2016-12-12 18:05:53 -05:00
$ docker rmi rootfsimage
2016-10-12 19:23:01 -04:00
```
2016-12-12 18:05:53 -05:00
#### The config.json file
2016-10-12 19:23:01 -04:00
2016-12-12 18:05:53 -05:00
The `config.json` file describes the plugin. See the [plugins config reference ](config.md ).
2016-10-20 14:12:02 -04:00
2016-11-07 21:51:47 -05:00
Consider the following `config.json` file.
2016-10-20 14:12:02 -04:00
```json
2016-10-12 19:23:01 -04:00
{
"description": "sshFS plugin for Docker",
"documentation": "https://docs.docker.com/engine/extend/plugins/",
2017-03-07 04:06:27 -05:00
"entrypoint": ["/docker-volume-sshfs"],
2016-10-12 19:23:01 -04:00
"network": {
"type": "host"
},
"interface" : {
"types": ["docker.volumedriver/1.0"],
"socket": "sshfs.sock"
},
2017-02-06 17:44:56 -05:00
"linux": {
"capabilities": ["CAP_SYS_ADMIN"]
}
2016-10-12 19:23:01 -04:00
}
```
2016-10-20 14:12:02 -04:00
This plugin is a volume driver. It requires a `host` network and the
2017-03-07 04:06:27 -05:00
`CAP_SYS_ADMIN` capability. It depends upon the `/docker-volume-sshfs`
2016-10-20 14:12:02 -04:00
entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate
2016-12-12 18:05:53 -05:00
with Docker Engine. This plugin has no runtime parameters.
2016-10-20 14:12:02 -04:00
2017-01-19 15:25:16 -05:00
#### Creating the plugin
2016-10-20 14:12:02 -04:00
2016-12-12 18:05:53 -05:00
A new plugin can be created by running
`docker plugin create <plugin-name> ./path/to/plugin/data` where the plugin
data contains a plugin configuration file `config.json` and a root filesystem
2017-02-14 19:40:15 -05:00
in subdirectory `rootfs` .
2016-10-20 14:12:02 -04:00
2016-12-12 18:05:53 -05:00
After that the plugin `<plugin-name>` will show up in `docker plugin ls` .
Plugins can be pushed to remote registries with
2017-01-19 15:25:16 -05:00
`docker plugin push <plugin-name>` .
2017-02-06 17:44:56 -05:00
## Debugging plugins
Stdout of a plugin is redirected to dockerd logs. Such entries have a
`plugin=<ID>` suffix. Here are a few examples of commands for pluginID
`f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62` and their
corresponding log entries in the docker daemon logs.
```bash
2017-08-07 05:04:05 -04:00
$ docker plugin install tiborvass/sample-volume-plugin
2017-02-06 17:44:56 -05:00
INFO[0036] Starting... Found 0 volumes on startup plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
```
```bash
2017-08-07 05:04:05 -04:00
$ docker volume create -d tiborvass/sample-volume-plugin samplevol
2017-02-06 17:44:56 -05:00
INFO[0193] Create Called... Ensuring directory /data/samplevol exists on host... plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] Created volume samplevol with mountpoint /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
```
```bash
$ docker run -v samplevol:/tmp busybox sh
INFO[0421] Get Called... Found samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Mount Called... Mounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Unmount Called... Unmounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
```
#### Using docker-runc to obtain logfiles and shell into the plugin.
`docker-runc` , the default docker container runtime can be used for debugging
plugins. This is specifically useful to collect plugin logs if they are
redirected to a file.
```bash
2018-04-05 15:14:59 -04:00
$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins list
ID PID STATUS BUNDLE CREATED OWNER
93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 15806 running /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 2018-02-08T21:40:08.621358213Z root
9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9 14992 running /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9 2018-02-08T21:35:12.321325872Z root
c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d 14984 running /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d 2018-02-08T21:35:12.321288966Z root
2017-02-06 17:44:56 -05:00
```
```bash
2018-04-05 15:14:59 -04:00
$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins exec 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 cat /var/log/plugin.log
2017-02-06 17:44:56 -05:00
```
If the plugin has a built-in shell, then exec into the plugin can be done as
follows:
```bash
2018-04-05 15:14:59 -04:00
$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins exec -t 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 sh
2017-02-06 17:44:56 -05:00
```
2017-02-10 17:08:36 -05:00
#### Using curl to debug plugin socket issues.
To verify if the plugin API socket that the docker daemon communicates with
2017-02-14 19:40:15 -05:00
is responsive, use curl. In this example, we will make API calls from the
2017-02-10 17:08:36 -05:00
docker host to volume and network plugins using curl 7.47.0 to ensure that
the plugin is listening on the said socket. For a well functioning plugin,
these basic requests should work. Note that plugin sockets are available on the host under `/var/run/docker/plugins/<pluginID>`
```bash
curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List
{"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null}
```
```bash
curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities
{"Scope":"local"}
```
2017-02-14 19:40:15 -05:00
When using curl 7.5 and above, the URL should be of the form
`http://hostname/APICall` , where `hostname` is the valid hostname where the
2017-02-10 17:08:36 -05:00
plugin is installed and `APICall` is the call to the plugin API.
For example, `http://localhost/VolumeDriver.List`