Make your Docker Compose applications reusable, and share them on Docker Hub
Перейти к файлу
Nicolas De Loof 0df017d9e7
When none set, generate a random installation name
For uniformity with `docker run` user experience.
Note a full implementation would required to get the engine manage
random name unicity, like it does for containers.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-10-01 09:55:39 +02:00
.github Fix github issue template 2019-08-19 18:48:35 +02:00
cmd cleanup 2019-09-09 14:38:43 +02:00
docs docs: Merge matrices and include docker-compose up. 2018-09-28 10:30:31 +02:00
e2e Merge pull request #648 from rumpl/feat-image-rm 2019-09-30 15:25:56 +02:00
examples remove the status command from docker app CLI 2019-09-27 17:08:45 +02:00
hack
internal When none set, generate a random installation name 2019-10-01 09:55:39 +02:00
loader Some more obsolete code 2019-09-10 11:16:35 +02:00
render Remove redundant env_file section. 2019-09-27 10:10:07 +02:00
specification Fix CRLF detection on single-file app + fix YAML documents order detection for single-file apps 2019-06-28 16:18:59 +02:00
types Some more obsolete code 2019-09-10 11:16:35 +02:00
vendor When none set, generate a random installation name 2019-10-01 09:55:39 +02:00
.dockerignore Simplify and enhance docker.Makefile 2018-06-11 13:48:00 +02:00
.fossa.yml Removed dependencies from .fossa file and turned on GOMODULE 2019-08-26 15:36:59 -07:00
.gitattributes Various cleanings, including missing EOL, typos, comments, ... 2019-01-31 16:46:37 +01:00
.gitignore Forbid variable substitution on `image` field 2019-02-05 11:28:06 +01:00
.golangci.yml ci: add all default-enabled golangci-lint linters 2019-04-05 14:33:54 +01:00
BUILDING.md os.ModeIrregular used by vendor/github.com/docker/cli/cli/command/utils.go:155 was introduced by go 1.11 2019-08-21 17:00:20 +02:00
CONTRIBUTING.md Prepare docker/app to be open-source 🎉 2018-06-12 15:29:38 +02:00
Dockerfile When none set, generate a random installation name 2019-10-01 09:55:39 +02:00
Dockerfile.invocation-image Dockerfile.invocation-image: Fix for multi-arch 2019-09-16 09:53:05 -05:00
Dockerfile.lint golang alpine image does not support subminor version 2019-08-19 16:53:07 +02:00
Gopkg.lock When none set, generate a random installation name 2019-10-01 09:55:39 +02:00
Gopkg.toml Revert "Bump github.com/xeipuuv/gojsonschema" 2019-09-25 15:17:38 +02:00
Jenkinsfile Remove 3rd party software integrations directory and related build steps from codebase 2019-09-16 11:35:41 +02:00
Jenkinsfile.baguette Only run FOSSA scan if we changed deps 2019-09-26 15:39:42 +02:00
LICENSE Prepare docker/app to be open-source 🎉 2018-06-12 15:29:38 +02:00
MAINTAINERS Removing myself from maintainers 2019-04-17 17:42:00 +02:00
Makefile Ensure invocation image has been build when running a make or make all command 2019-09-25 12:25:17 +02:00
README.md remove the status command from docker app CLI 2019-09-27 17:08:45 +02:00
doc.go Add package doc for the root package… 2018-09-06 16:39:39 +02:00
docker.Makefile Remove 3rd party software integrations directory and related build steps from codebase 2019-09-16 11:35:41 +02:00
poule.yml Prepare docker/app to be open-source 🎉 2018-06-12 15:29:38 +02:00
vars.mk Bump FOSSA image 2019-09-30 13:09:06 +02:00

README.md

Docker Application

A Docker CLI Plugin to configure, share and install applications:

  • Extend Compose files with metadata and parameters
  • Re-use same application across multiple environments (Development/QA/Staging/Production)
  • Multi orchestrator installation (Swarm or Kubernetes)
  • Push/Pull/Promotion/Signing supported for application, with same workflow as images
  • Fully CNAB compliant
  • Full support of Docker Contexts

The problem Application Packages solves

Compose files do a great job of describing a set of related services. Not only are Compose files easy to write, they are generally easy to read as well. However, a couple of problems often emerge:

  1. You have several environments where you want to deploy the application, with small configuration differences
  2. You have lots of similar applications

Fundamentally, Compose files are not easy to share between concerns. Docker Application Packages aim to solve these problems and make Compose more useful for development and production.

Looking at an example

Let's take the following Compose file. It launches an HTTP server which prints the specified text when hit on the configured port.

version: '3.2'
services:
  hello:
    image: hashicorp/http-echo
    command: ["-text", "hello world"]
    ports:
      - 5678:5678

With docker app installed let's create an Application Package based on this Compose file:

$ docker app init hello
$ ls
docker-compose.yml
hello.dockerapp

We created a new folder hello.dockerapp that contains three YAML documents:

  • metadata
  • the Compose file
  • parameters for your application

It should look like this:

version: 0.1.0
name: hello
description: A simple text server
maintainers:
- name: yourusername
  email:
version: '3.2'
services:
  hello:
    image: hashicorp/http-echo
    command: ["-text", "hello world"]
    ports:
      - 5678:5678

And an empty `parameters.yml. Let's edit and add the following default values for our applicatoin

port: 5678
text: hello development

Then modify the Compose file section in hello.dockerapp, adding in the variables.

version: '3.2'
services:
  hello:
    image: hashicorp/http-echo
    command: ["-text", "${text}"]
    ports:
      - ${port}:5678

You can test everything is working, by inspecting the application definition.

$ docker app inspect
hello 0.1.0

Maintained by: yourusername

A simple text server

Service (1) Replicas Ports Image
----------- -------- ----- -----
hello       1        5678  hashicorp/http-echo

Parameters (2) Value
-------------- -----
port           5678
text           hello development

You can render the application to a Compose file with the provided default values.

$ docker app render
version: "3.2"
services:
  hello:
    command:
    - -text
    - hello development
    image: hashicorp/http-echo
    ports:
    - mode: ingress
      target: 5678
      published: 5678
      protocol: tcp

You can then use that Compose file like any other. You could save it to disk or pipe it straight to docker stack or docker-compose to run the application.

$ docker app render | docker-compose -f - up

This is where it gets interesting. We can override those parameters at runtime, using the --set option. Let's specify some different options and run render again:

$ docker app render --set port=4567 --set text="hello production"
version: "3.2"
services:
  hello:
    command:
    - -text
    - hello production
    image: hashicorp/http-echo
    ports:
    - mode: ingress
      target: 5678
      published: 4567
      protocol: tcp

If you prefer you can create a standalone configuration file to store those parameters. Let's create prod.yml with the following contents:

text: hello production
port: 4567

You can then run using that configuration file like so:

$ docker app render --parameters-file prod.yml

You can share your Application Package by pushing it to a container registry.

$ docker app push --tag myrepo/hello:0.1.0

Others can then use your Application Package by specifying the registry tag.

$ docker app inspect myrepo/hello:0.1.0

Note: Commands like install, upgrade, render, etc. can also be used directly on Application Packages that are in a registry.

You can specify the Docker endpoint where an application is installed using a context and the --target-context option. If you do not specify one, it will use the currently active context.

$ docker context create remote --description "remote cluster" --docker host=tcp://<remote-ip>:<remote-port>
Successfully created context "remote"

$ docker context ls
NAME                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT                ORCHESTRATOR
default *           Current DOCKER_HOST based configuration   unix:///var/run/docker.sock   https://localhost:6443 (default)   swarm
remote              remote cluster                            tcp://<remote-ip>:<remote-port>

$ docker app install myrepo/hello:0.1.0 --target-context remote
...

More examples are available in the examples directory.

CNAB

Under the hood docker app is CNAB compliant. It generates a CNAB from your application source and is able to install and manage any other CNAB too. CNAB specifies three actions which docker app provides as commands:

  • install
  • upgrade
  • uninstall

Here is an example installing an Application Package, querying its status and then uninstalling it:

$ docker app install examples/hello-world/example-hello-world.dockerapp --name hello
Creating network hello_default
Creating service hello_hello

$ docker app status hello
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
0m1wn7jrgkgj        hello_hello         replicated          1/1                 hashicorp/http-echo:latest   *:8080->5678/tcp

$ docker app uninstall hello
Removing service hello_hello
Removing network hello_default

Installation

Note: This requires a pre-release version (19.03.0 beta 1 or later) of the Docker CLI.

Pre-built static binaries are available on GitHub releases for Windows, Linux and macOS. Each tarball contains two binaries:

  • docker-app-plugin-{linux|darwin|windows.exe} which is a Docker CLI plugin. Note: This requires a pre-release version of the Docker CLI
  • docker-app-standalone-{linux|darwin|windows.exe} which is a standalone utility

To use the standalone version, use docker-app instead of docker app and all the examples will work the same way.

Linux or macOS

Download your OS tarball:

export OSTYPE="$(uname | tr A-Z a-z)"
curl -fsSL --output "/tmp/docker-app-${OSTYPE}.tar.gz" "https://github.com/docker/app/releases/download/v0.8.0/docker-app-${OSTYPE}.tar.gz"
tar xf "/tmp/docker-app-${OSTYPE}.tar.gz" -C /tmp/

To install as standalone:

install -b "/tmp/docker-app-standalone-${OSTYPE}" /usr/local/bin/docker-app

To install as a Docker CLI plugin:

mkdir -p ~/.docker/cli-plugins && cp "/tmp/docker-app-plugin-${OSTYPE}" ~/.docker/cli-plugins/docker-app

Windows

Download the Windows tarball:

Invoke-WebRequest -Uri https://github.com/docker/app/releases/download/v0.8.0/docker-app-windows.tar.gz -OutFile docker-app.tar.gz -UseBasicParsing
tar xf "docker-app.tar.gz"

To install as standalone, copy it somewhere in your path:

cp docker-app-standalone-windows.exe PATH/docker-app.exe

To install as a Docker CLI plugin:

New-Item -ItemType Directory -Path ~/.docker/cli-plugins -ErrorAction SilentlyContinue
cp docker-app-plugin-windows.exe ~/.docker/cli-plugins/docker-app.exe

Attachments (Storing additional files)

If you want to store additional files in the application package, such as prod.yml, test.yml or other config files, use the directory format and simply place these files inside the *.dockerapp/ directory. These will be bundled into the package when using docker app push.

Sharing your application on the Hub

You can push any application to the Hub (or any registry) using docker app push:

$ docker app push --tag myhubuser/myimage:latest

This command will push an image named myhubuser/myimage:latest to the Docker Hub.

If you omit the --tag myhubuser/myimage:latest argument, this command uses the application name and version defined in metadata.yml as the tag: name:version.

All docker app commands accept an image name as input, which means you can run on a different host:

$ docker app inspect myhubuser/myimage

The first time a command is executed against a given image name the bundle is pulled from the registry and put in the local bundle store. You can pre-populate this store by running docker app pull myhubuser/myimage:latest. All commands manipulating a package also accept a --pull flag to force pulling the bundle from the registry, even if it is present in the local store. This can be useful when you are repeatedly pushing a bundle on the same tag.

Multi-arch applications

By default the docker app push command only pushes service images for the linux/amd64 platform to the Docker Hub. By using the the --all-platforms flag it is possible to push the services images for all platforms:

$ docker app push --all-platforms myhubuser/myimage

It is also possible to push only a limited subset of platforms with the --platform flag:

$ docker app push --platform linux/amd64 --platform linux/arm64 --platform linux/arm/v7 myhubuser/myimage

Next steps

If you're interested in contributing to the project, jump to BUILDING.md and CONTRIBUTING.md.

Usage

$ docker app

Usage:  docker app COMMAND

A tool to build and manage Docker Applications.

Commands:
  bundle      Create a CNAB invocation image and `bundle.json` for the application
  completion  Generates completion scripts for the specified shell (bash or zsh)
  init        Initialize Docker Application definition
  inspect     Shows metadata, parameters and a summary of the Compose file for a given application
  install     Install an application
  ls          List the installations and their last known installation result
  pull        Pull an application package from a registry
  push        Push an application package to a registry
  render      Render the Compose file for an Application Package
  rm          Remove an application
  upgrade     Upgrade an installed application
  validate    Checks the rendered application is syntactically correct

Run 'docker app COMMAND --help' for more information on a command.

Experimental

Some commands are flagged as experimental and will remain in this state until they mature. These commands are only accessible using an experimental binary. Feel free to test these commands and give us some feedback!

See BUILDING.md/Experimental.