github.com/docker/docker-ce@v17.12.1-ce-rc2+incompatible/components/cli/docs/extend/index.md (about) 1 --- 2 description: Develop and use a plugin with the managed plugin system 3 keywords: "API, Usage, plugins, documentation, developer" 4 --- 5 6 <!-- This file is maintained within the docker/cli GitHub 7 repository at https://github.com/docker/cli/. Make all 8 pull requests against that repo. If you see this file in 9 another repository, consider it read-only there, as it will 10 periodically be overwritten by the definitive file. Pull 11 requests which include edits to this file in other repositories 12 will be rejected. 13 --> 14 15 # Docker Engine managed plugin system 16 17 * [Installing and using a plugin](index.md#installing-and-using-a-plugin) 18 * [Developing a plugin](index.md#developing-a-plugin) 19 * [Debugging plugins](index.md#debugging-plugins) 20 21 Docker Engine's plugin system allows you to install, start, stop, and remove 22 plugins using Docker Engine. 23 24 For information about the legacy plugin system available in Docker Engine 1.12 25 and earlier, see [Understand legacy Docker Engine plugins](legacy_plugins.md). 26 27 > **Note**: Docker Engine managed plugins are currently not supported 28 on Windows daemons. 29 30 ## Installing and using a plugin 31 32 Plugins are distributed as Docker images and can be hosted on Docker Hub or on 33 a private registry. 34 35 To install a plugin, use the `docker plugin install` command, which pulls the 36 plugin from Docker Hub or your private registry, prompts you to grant 37 permissions or capabilities if necessary, and enables the plugin. 38 39 To check the status of installed plugins, use the `docker plugin ls` command. 40 Plugins that start successfully are listed as enabled in the output. 41 42 After a plugin is installed, you can use it as an option for another Docker 43 operation, such as creating a volume. 44 45 In the following example, you install the `sshfs` plugin, verify that it is 46 enabled, and use it to create a volume. 47 48 > **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. 49 50 1. Install the `sshfs` plugin. 51 52 ```bash 53 $ docker plugin install vieux/sshfs 54 55 Plugin "vieux/sshfs" is requesting the following privileges: 56 - network: [host] 57 - capabilities: [CAP_SYS_ADMIN] 58 Do you grant the above permissions? [y/N] y 59 60 vieux/sshfs 61 ``` 62 63 The plugin requests 2 privileges: 64 65 - It needs access to the `host` network. 66 - It needs the `CAP_SYS_ADMIN` capability, which allows the plugin to run 67 the `mount` command. 68 69 2. Check that the plugin is enabled in the output of `docker plugin ls`. 70 71 ```bash 72 $ docker plugin ls 73 74 ID NAME TAG DESCRIPTION ENABLED 75 69553ca1d789 vieux/sshfs latest the `sshfs` plugin true 76 ``` 77 78 3. Create a volume using the plugin. 79 This example mounts the `/remote` directory on host `1.2.3.4` into a 80 volume named `sshvolume`. 81 82 This volume can now be mounted into containers. 83 84 ```bash 85 $ docker volume create \ 86 -d vieux/sshfs \ 87 --name sshvolume \ 88 -o sshcmd=user@1.2.3.4:/remote \ 89 -o password=$(cat file_containing_password_for_remote_host) 90 91 sshvolume 92 ``` 93 4. Verify that the volume was created successfully. 94 95 ```bash 96 $ docker volume ls 97 98 DRIVER NAME 99 vieux/sshfs sshvolume 100 ``` 101 102 5. Start a container that uses the volume `sshvolume`. 103 104 ```bash 105 $ docker run --rm -v sshvolume:/data busybox ls /data 106 107 <content of /remote on machine 1.2.3.4> 108 ``` 109 110 6. Remove the volume `sshvolume` 111 ```bash 112 docker volume rm sshvolume 113 114 sshvolume 115 ``` 116 To disable a plugin, use the `docker plugin disable` command. To completely 117 remove it, use the `docker plugin remove` command. For other available 118 commands and options, see the 119 [command line reference](../reference/commandline/index.md). 120 121 122 ## Developing a plugin 123 124 #### The rootfs directory 125 The `rootfs` directory represents the root filesystem of the plugin. In this 126 example, it was created from a Dockerfile: 127 128 >**Note:** The `/run/docker/plugins` directory is mandatory inside of the 129 plugin's filesystem for docker to communicate with the plugin. 130 131 ```bash 132 $ git clone https://github.com/vieux/docker-volume-sshfs 133 $ cd docker-volume-sshfs 134 $ docker build -t rootfsimage . 135 $ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created 136 $ sudo mkdir -p myplugin/rootfs 137 $ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs 138 $ docker rm -vf "$id" 139 $ docker rmi rootfsimage 140 ``` 141 142 #### The config.json file 143 144 The `config.json` file describes the plugin. See the [plugins config reference](config.md). 145 146 Consider the following `config.json` file. 147 148 ```json 149 { 150 "description": "sshFS plugin for Docker", 151 "documentation": "https://docs.docker.com/engine/extend/plugins/", 152 "entrypoint": ["/docker-volume-sshfs"], 153 "network": { 154 "type": "host" 155 }, 156 "interface" : { 157 "types": ["docker.volumedriver/1.0"], 158 "socket": "sshfs.sock" 159 }, 160 "linux": { 161 "capabilities": ["CAP_SYS_ADMIN"] 162 } 163 } 164 ``` 165 166 This plugin is a volume driver. It requires a `host` network and the 167 `CAP_SYS_ADMIN` capability. It depends upon the `/docker-volume-sshfs` 168 entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate 169 with Docker Engine. This plugin has no runtime parameters. 170 171 #### Creating the plugin 172 173 A new plugin can be created by running 174 `docker plugin create <plugin-name> ./path/to/plugin/data` where the plugin 175 data contains a plugin configuration file `config.json` and a root filesystem 176 in subdirectory `rootfs`. 177 178 After that the plugin `<plugin-name>` will show up in `docker plugin ls`. 179 Plugins can be pushed to remote registries with 180 `docker plugin push <plugin-name>`. 181 182 183 ## Debugging plugins 184 185 Stdout of a plugin is redirected to dockerd logs. Such entries have a 186 `plugin=<ID>` suffix. Here are a few examples of commands for pluginID 187 `f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62` and their 188 corresponding log entries in the docker daemon logs. 189 190 ```bash 191 $ docker plugin install tiborvass/sample-volume-plugin 192 193 INFO[0036] Starting... Found 0 volumes on startup plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 194 ``` 195 196 ```bash 197 $ docker volume create -d tiborvass/sample-volume-plugin samplevol 198 199 INFO[0193] Create Called... Ensuring directory /data/samplevol exists on host... plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 200 INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 201 INFO[0193] Created volume samplevol with mountpoint /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 202 INFO[0193] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 203 ``` 204 205 ```bash 206 $ docker run -v samplevol:/tmp busybox sh 207 208 INFO[0421] Get Called... Found samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 209 INFO[0421] Mount Called... Mounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 210 INFO[0421] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 211 INFO[0421] Unmount Called... Unmounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 212 ``` 213 214 #### Using docker-runc to obtain logfiles and shell into the plugin. 215 216 `docker-runc`, the default docker container runtime can be used for debugging 217 plugins. This is specifically useful to collect plugin logs if they are 218 redirected to a file. 219 220 ```bash 221 $ docker-runc list 222 ID PID STATUS BUNDLE CREATED 223 f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 2679 running /run/docker/libcontainerd/f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 2017-02-06T21:53:03.031537592Z 224 r 225 ``` 226 227 ```bash 228 $ docker-runc exec f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 cat /var/log/plugin.log 229 ``` 230 231 If the plugin has a built-in shell, then exec into the plugin can be done as 232 follows: 233 ```bash 234 $ docker-runc exec -t f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 sh 235 ``` 236 237 #### Using curl to debug plugin socket issues. 238 239 To verify if the plugin API socket that the docker daemon communicates with 240 is responsive, use curl. In this example, we will make API calls from the 241 docker host to volume and network plugins using curl 7.47.0 to ensure that 242 the plugin is listening on the said socket. For a well functioning plugin, 243 these basic requests should work. Note that plugin sockets are available on the host under `/var/run/docker/plugins/<pluginID>` 244 245 246 ```bash 247 curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List 248 249 {"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null} 250 ``` 251 252 ```bash 253 curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities 254 255 {"Scope":"local"} 256 ``` 257 When using curl 7.5 and above, the URL should be of the form 258 `http://hostname/APICall`, where `hostname` is the valid hostname where the 259 plugin is installed and `APICall` is the call to the plugin API. 260 261 For example, `http://localhost/VolumeDriver.List`