Make your Docker Compose applications reusable, and share them on Docker Hub
Перейти к файлу
Silvin Lubecki b4a8a4a6f9 Bump docker/cli
Bump docker/docker
Fix last changes on context stores made on docker/cli (the main store interface has been split to multiple smaller interfaces).

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2019-05-23 16:58:59 +02:00
.github Update code owners according to current project setup 😉 2018-12-06 09:37:11 +01:00
cmd Merge pull request #509 from chris-crone/ux-cleanup 2019-04-18 13:01:40 +02:00
docs docs: Merge matrices and include docker-compose up. 2018-09-28 10:30:31 +02:00
e2e Merge pull request #531 from ijc/individual-credentials 2019-05-17 10:59:54 +02:00
examples Rework examples 2019-04-18 13:05:39 +02:00
hack Add a vendor check 2018-06-11 11:31:03 +02:00
integrations Remove '_' in volume's name as it is invalid with kubernetes. 2019-01-08 15:52:28 +01:00
internal Bump docker/cli 2019-05-23 16:58:59 +02:00
loader Remove loading app from an URL 2019-02-14 16:41:14 +01:00
pkg/yatee Update `nolint` comments. 2019-04-05 14:33:54 +01:00
render - Update k8s dependencies to 1.14.0 2019-04-17 11:27:39 +02:00
specification Remove namespace & repo opts form push and bump v2 2019-02-20 15:05:47 +01:00
types metadata: Add helper to extract docker-app metadata from a bundle. 2019-05-13 11:41:35 +01:00
vendor Bump docker/cli 2019-05-23 16:58:59 +02:00
.dockerignore Simplify and enhance docker.Makefile 2018-06-11 13:48:00 +02: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 Refactor invocation image build 2019-02-08 11:00:50 +01:00
CONTRIBUTING.md Prepare docker/app to be open-source 🎉 2018-06-12 15:29:38 +02:00
Dockerfile Only build CLI for platforms we need 2019-04-18 15:05:43 +02:00
Dockerfile.gradle gradle: Pin version as current latest image is broken. 2018-08-28 12:57:43 +02:00
Dockerfile.invocation-image Bump Golang, dep, alpine 2019-04-17 11:52:30 +02:00
Dockerfile.lint Bump Golang, dep, alpine 2019-04-17 11:52:30 +02:00
Gopkg.lock Bump docker/cli 2019-05-23 16:58:59 +02:00
Gopkg.toml Move to kube 1.14.1 2019-04-17 11:48:41 +02:00
Jenkinsfile Update the Makefiles and Jenkinsfiles to prepare the release of Docker App 2019-04-08 17:48:02 +02:00
Jenkinsfile.baguette Update the Makefiles and Jenkinsfiles to prepare the release of Docker App 2019-04-08 17:48:02 +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 ci: Switch from gometalinter to golangci-lint 2019-04-05 14:33:54 +01:00
README.md Add a TL;DR at the top of the README 2019-04-26 11:55:34 +02:00
doc.go Add package doc for the root package… 2018-09-06 16:39:39 +02:00
docker.Makefile ci: ensure we always get the test results even if they fail 2019-04-05 14:33:54 +01:00
poule.yml Prepare docker/app to be open-source 🎉 2018-06-12 15:29:38 +02:00
vars.mk Bump Golang, dep, alpine 2019-04-17 11:52:30 +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 --single-file hello
$ ls
docker-compose.yml
hello.dockerapp

We created a new file 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

---
{}

Let's edit the parameters section and add the following default values for our application:

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.6.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.6.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-plugin-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

Single file or directory representation

If you prefer having the three core documents in separate YAML files, omit the --single-file option to the docker app init command. This will create a directory instead of a single file, containing metadata.yml, docker-compose.yml and parameters.yml.

Converting between the two formats can be achieved by using the docker app split and docker app merge commands.

Note: You cannot store attachments in the single file format. If you want to use attachments you should use the directory format.

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.

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
  list        List the installations and their last known installation result
  merge       Merge a directory format Docker Application definition into a single file
  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
  split       Split a single-file Docker Application definition into the directory format
  status      Get the installation status of an application
  uninstall   Uninstall an application
  upgrade     Upgrade an installed application
  validate    Checks the rendered application is syntactically correct
  version     Print version information

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

Shell completion

Bash

Load the completion code for bash into the current shell:

$ source <(docker app completion bash)

Set the completion code for bash to autoload on startup in your ~/.bashrc, ~/.profile or ~/.bash_profile:

source <(docker app completion bash)

Note: bash-completion is needed.

Zsh

Load the completion code for zsh into the current shell

$ source <(docker app completion zsh)

Set the completion code for zsh to autoload on startup in your ~/.zshrc

source <(docker app completion zsh)

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.