-
Notifications
You must be signed in to change notification settings - Fork 37
Ideal Plugin Development Environment
Our experience with Overview plugins leads us to these best practices for developing plugins.
These are all guidelines, not rules. They explain how people expect to create, maintain and consume an Overview plugin.
Users should be able to develop the plugin with two steps:
- Download and run
overview-server
's./dev
- Download and run your plugin's
./dev
The contract:
- The plugin listens within a Docker container with
--network=overviewserver_default
. - The Docker container is an HTTP server listening on port 80. It's redirected to port 3334 on localhost: that is,
./dev
invokes Docker with--publish 127.0.0.1:3334:80
. - The Docker container has a fixed name, so it can be used by
integration-test/run
. - The Docker container "recompiles" (as in, adjusts its outputs) when you edit source code. The usual way to do this is to mount your source code in read-only
--volume
arguments. Recompilation should be quick. - The Docker container does not write any files.
- You can cancel the server using
Ctrl+C
. - Bonus points: during recompilation, your Docker container runs unit tests and outputs results to a console.
You desperately need integration tests for your plugin. You can install integration tests with a single command: see overview-integration-tester.
See overview-integration-tester
for the contract. Basically, this should spin up and shut down an entire Overview environment including your plugin (built using your Dockerfile
) and verify that your plugin actually does things. This mimics how your plugin will behave in overview-local
.
We publish all plugins as Docker images on Docker Hub, so overview-local can download and run them locally.
Usually, a production image has very different files than a development image. Make a modest effort not to inflate the image size of the production image.
The contract:
- It's a multi-stage build.
- A
development
stage is there for./dev
- A
production
stage creates a Docker image that runs an HTTP server listening on port 80. This is the final stage, forintegration-test/run-in-docker-compose
and Docker Hub
The ./release
command should push a new version online, so other projects (such as overview-local) can use it.
The contract:
- The version number should follow semver, and the
MAJOR
version should always be1
. - It should push
master
andv1.0.1
to GitHub. - Docker Hub's Automated Build should have triggers to build major, minor and patch versions. For instance, the "patch" trigger (i.e., the one that creates Docker image version
:1.0.1
) should haveType=Tag
,Name=/^v([0-9]+)\.([0-9]+)\.([0-9]+)$/
,Dockerfile Location=/
,Docker Tag Name={\1}.{\2}.{\3}
.
For a plugin with a server component, ./release
is the best you can do. Tell your users to download the new version when it's available.
If your plugin is a static site, though, you don't need a Docker container on production. You can serve your plugin using an S3 bucket to save money.
We recommend using in-memory-website to simplify this workflow. Picture it:
-
./dev
uses thedevelopment
Dockerfile stage to watch for file changes, write the entire website to a single file, and serve the website from that single file using in-memory-website-http-server. - A
build
Dockerfile stage inherits thedevelopment
stage and compiles the in-memory website to a file. - The
production
Dockerfile stage inheritsadamhooper/in-memory-website-http-server
and copies the file from thebuild
stage. -
./deploy
uploads the in-memory website to S3.
This makes development pleasant because you can be confident that the static site served in production
is as similar as possible to the static site served from S3.