447 lines
15 KiB
Markdown
447 lines
15 KiB
Markdown
---
|
|
title: Docker App
|
|
description: Learn about Docker App
|
|
keywords: Docker App, applications, compose, orchestration
|
|
---
|
|
|
|
>This is an experimental feature.
|
|
>
|
|
>{% include experimental.md %}
|
|
|
|
## Overview
|
|
|
|
Docker App is a CLI plug-in that introduces a top-level `docker app` command to bring
|
|
the _container experience_ to applications. The following table compares Docker containers with Docker applications.
|
|
|
|
|
|
| Object | Config file | Build with | Execute with | Share with |
|
|
| ------------- |---------------| -------------------|-----------------------|-------------------|
|
|
| Container | Dockerfile | docker image build | docker container run | docker image push |
|
|
| App | App Package | docker app bundle | docker app install | docker app push |
|
|
|
|
|
|
With Docker App, entire applications can now be managed as easily as images and containers. For example,
|
|
Docker App lets you _build_, _validate_ and _deploy_ applications with the `docker app` command. You can
|
|
even leverage secure supply-chain features such as signed `push` and `pull` operations.
|
|
|
|
> **NOTE**: `docker app` works with `Docker 19.03` or higher.
|
|
|
|
This guide walks you through two scenarios:
|
|
|
|
1. Initialize and deploy a new Docker App project from scratch.
|
|
1. Convert an existing Compose app into a Docker App project (added later in the beta process).
|
|
|
|
The first scenario describes basic components of a Docker App with tools and workflow.
|
|
|
|
## Initialize and deploy a new Docker App project from scratch
|
|
|
|
This section describes the steps for creating a new Docker App project to familiarize you with the workflow and most important commands.
|
|
|
|
1. Prerequisites
|
|
1. Initialize an empty new project
|
|
1. Populate the project
|
|
1. Validate the app
|
|
1. Deploy the app
|
|
1. Push the app to Docker Hub
|
|
1. Install the app directly from Docker Hub
|
|
|
|
### Prerequisites
|
|
|
|
You need at least one Docker node operating in Swarm mode. You also need the latest build of the Docker CLI
|
|
with the App CLI plugin included.
|
|
|
|
Depending on your Linux distribution and your security context, you might need to prepend commands with `sudo`.
|
|
|
|
### Initialize a new empty project
|
|
|
|
The `docker app init` command is used to initialize a new Docker application project. If you run it on
|
|
its own, it initializes a new empty project. If you point it to an existing `docker-compose.yml` file,
|
|
it initializes a new project based on the Compose file.
|
|
|
|
Use the following command to initialize a new empty project called "hello-world".
|
|
|
|
```
|
|
$ docker app init --single-file hello-world
|
|
Created "hello-world.dockerapp"
|
|
```
|
|
|
|
The command produces a single file in your current directory called `hello-world.dockerapp`.
|
|
The format of the file name is <project-name> appended with `.dockerapp`.
|
|
|
|
```
|
|
$ ls
|
|
hello-world.dockerapp
|
|
```
|
|
|
|
If you run `docker app init` without the `--single-file` flag, you get a new directory containing three YAML files.
|
|
The name of the directory is the name of the project with `.dockerapp` appended, and the three YAML files are:
|
|
|
|
- `docker-compose.yml`
|
|
- `metadata.yml`
|
|
- `parameters.yml`
|
|
|
|
However, the `--single-file` option merges the three YAML files into a single YAML file with three sections.
|
|
Each of these sections relates to one of the three YAML files mentioned previously: `docker-compose.yml`,
|
|
`metadata.yml`, and `parameters.yml`. Using the `--single-file` option enables you to share your application
|
|
using a single configuration file.
|
|
|
|
Inspect the YAML with the following command.
|
|
|
|
```
|
|
$ cat hello-world.dockerapp
|
|
# Application metadata - equivalent to metadata.yml.
|
|
version: 0.1.0
|
|
name: hello-world
|
|
description:
|
|
---
|
|
# Application services - equivalent to docker-compose.yml.
|
|
version: "3.6"
|
|
services: {}
|
|
---
|
|
# Default application parameters - equivalent to parameters.yml.
|
|
```
|
|
|
|
Your file might be more verbose.
|
|
|
|
Notice that each of the three sections is separated by a set of three dashes ("---"). Let's quickly describe each section.
|
|
|
|
The first section of the file specifies identification metadata such as name, version,
|
|
description and maintainers. It accepts key-value pairs. This part of the file can be a separate file called `metadata.yml`
|
|
|
|
The second section of the file describes the application. It can be a separate file called `docker-compose.yml`.
|
|
|
|
The final section specifies default values for application parameters. It can be a separate file called `parameters.yml`
|
|
|
|
### Populate the project
|
|
|
|
This section describes editing the project YAML file so that it runs a simple web app.
|
|
|
|
Use your preferred editor to edit the `hello-world.dockerapp` YAML file and update the application section with
|
|
the following information:
|
|
|
|
```
|
|
version: "3.6"
|
|
services:
|
|
hello:
|
|
image: hashicorp/http-echo
|
|
command: ["-text", "${hello.text}"]
|
|
ports:
|
|
- ${hello.port}:5678
|
|
```
|
|
|
|
Update the `Parameters` section to the following:
|
|
|
|
```
|
|
hello:
|
|
port: 8080
|
|
text: Hello world!
|
|
```
|
|
|
|
The sections of the YAML file are currently order-based. This means it's important they remain in the order we've explained, with the _metadata_ section being first, the _app_ section being second, and the _parameters_ section being last. This may change to name-based sections in future releases.
|
|
|
|
Save the changes.
|
|
|
|
The application is updated to run a single-container application based on the `hashicorp/http-echo` web server image.
|
|
This image has it execute a single command that displays some text and exposes itself on a network port.
|
|
|
|
Following best practices, the configuration of the application is decoupled from the application itself using variables.
|
|
In this case, the text displayed by the app and the port on which it will be published are controlled by two variables defined in the `Parameters` section of the file.
|
|
|
|
Docker App provides the `inspect` subcommand to provide a prettified summary of the application configuration.
|
|
It is a quick way to check how to configure the application before deployment, without having to read
|
|
the `Compose file`. It's important to note that the application is not running at this point, and that
|
|
the `inspect` operation inspects the configuration file(s).
|
|
|
|
```
|
|
$ docker app inspect hello-world.dockerapp
|
|
hello-world 0.1.0
|
|
|
|
Service (1) Replicas Ports Image
|
|
----------- -------- ----- -----
|
|
hello 1 8080 hashicorp/http-echo
|
|
|
|
Parameters (2) Value
|
|
-------------- -----
|
|
hello.port 8080
|
|
hello.text Hello world!
|
|
```
|
|
|
|
`docker app inspect` operations fail if the `Parameters` section doesn't specify a default value for
|
|
every parameter expressed in the app section.
|
|
|
|
The application is ready to be validated and rendered.
|
|
|
|
### Validate the app
|
|
|
|
Docker App provides the `validate` subcommand to check syntax and other aspects of the configuration.
|
|
If the app passes validation, the command returns no arguments.
|
|
|
|
```
|
|
$ docker app validate hello-world.dockerapp
|
|
Validated "hello-world.dockerapp"
|
|
```
|
|
|
|
`docker app validate` operations fail if the `Parameters` section doesn't specify a default value for
|
|
every parameter expressed in the app section.
|
|
|
|
As the `validate` operation has returned no problems, the app is ready to be deployed.
|
|
|
|
### Deploy the app
|
|
|
|
There are several options for deploying a Docker App project.
|
|
|
|
- Deploy as a native Docker App application
|
|
- Deploy as a Compose app application
|
|
- Deploy as a Docker Stack application
|
|
|
|
All three options are discussed, starting with deploying as a native Docker App application.
|
|
|
|
#### Deploy as a native Docker App
|
|
|
|
The process for deploying as a native Docker app is as follows:
|
|
|
|
Use `docker app install` to deploy the application.
|
|
|
|
Use the following command to deploy (install) the application.
|
|
|
|
```
|
|
$ docker app install hello-world.dockerapp --name my-app
|
|
Creating network my-app_default
|
|
Creating service my-app_hello
|
|
Application "my-app" installed on context "default"
|
|
```
|
|
|
|
By default, `docker app` uses the [current context](/engine/context/working-with-contexts) to run the
|
|
installation container and as a target context to deploy the application. You can override the second context
|
|
using the flag `--target-context` or by using the environment variable `DOCKER_TARGET_CONTEXT`. This flag is also
|
|
available for the commands `status`, `upgrade`, and `uninstall`.
|
|
|
|
```
|
|
$ docker app install hello-world.dockerapp --name my-app --target-context=my-big-production-cluster
|
|
Creating network my-app_default
|
|
Creating service my-app_hello
|
|
Application "my-app" installed on context "my-big-production-cluster"
|
|
```
|
|
|
|
> **Note**: Two applications deployed on the same target context cannot share the same name, but this is
|
|
valid if they are deployed on different target contexts.
|
|
|
|
You can check the status of the app with the `docker app status <app-name>` command.
|
|
|
|
```
|
|
$ docker app status my-app
|
|
INSTALLATION
|
|
------------
|
|
Name: my-app
|
|
Created: 35 seconds
|
|
Modified: 31 seconds
|
|
Revision: 01DCMY7MWW67AY03B029QATXFF
|
|
Last Action: install
|
|
Result: SUCCESS
|
|
Orchestrator: swarm
|
|
|
|
APPLICATION
|
|
-----------
|
|
Name: hello-world
|
|
Version: 0.1.0
|
|
Reference:
|
|
|
|
PARAMETERS
|
|
----------
|
|
hello.port: 8080
|
|
hello.text: Hello, World!
|
|
|
|
STATUS
|
|
------
|
|
ID NAME MODE REPLICAS IMAGE PORTS
|
|
miqdk1v7j3zk my-app_hello replicated 1/1 hashicorp/http-echo:latest *:8080->5678/tcp
|
|
```
|
|
|
|
The app is deployed using the stack orchestrator. This means you can also inspect it using the regular `docker stack` commands.
|
|
|
|
```
|
|
$ docker stack ls
|
|
NAME SERVICES ORCHESTRATOR
|
|
my-app 1 Swarm
|
|
```
|
|
|
|
Now that the app is running, you can point a web browser at the DNS name or public IP of the Docker node on
|
|
port 8080 and see the app. You must ensure traffic to port 8080 is allowed on
|
|
the connection from your browser to your Docker host.
|
|
|
|
Now change the port of the application using `docker app upgrade <app-name>` command.
|
|
```
|
|
$ docker app upgrade my-app --set hello.port=8181
|
|
Upgrading service my-app_hello
|
|
Application "my-app" upgraded on context "default"
|
|
```
|
|
|
|
You can uninstall the app with `docker app uninstall my-app`.
|
|
|
|
#### Deploy as a Docker Compose app
|
|
|
|
The process for deploying as a Compose app comprises two major steps:
|
|
|
|
1. Render the Docker app project as a `docker-compose.yml` file.
|
|
2. Deploy the app using `docker-compose up`.
|
|
|
|
You need a recent version of Docker Compose to complete these steps.
|
|
|
|
Rendering is the process of reading the entire application configuration and outputting it as a single `docker-compose.yml` file. This creates a Compose file with hard-coded values wherever a parameter was specified as a variable.
|
|
|
|
Use the following command to render the app to a Compose file called `docker-compose.yml` in the current directory.
|
|
|
|
```
|
|
$ docker app render --output docker-compose.yml hello-world.dockerapp
|
|
```
|
|
|
|
Check the contents of the resulting `docker-compose.yml` file.
|
|
|
|
```
|
|
$ cat docker-compose.yml
|
|
version: "3.6"
|
|
services:
|
|
hello:
|
|
command:
|
|
- -text
|
|
- Hello world!
|
|
image: hashicorp/http-echo
|
|
ports:
|
|
- mode: ingress
|
|
target: 5678
|
|
published: 8080
|
|
protocol: tcp
|
|
```
|
|
|
|
Notice that the file contains hard-coded values that were expanded based on the contents of the `Parameters`
|
|
section of the project's YAML file. For example, `${hello.text}` has been expanded to "Hello world!".
|
|
|
|
> **Note**: Almost all the `docker app` commands propose the `--set key=value` flag to override a default parameter.
|
|
|
|
Try to render the application with a different text:
|
|
|
|
```
|
|
$ docker app render hello-world.dockerapp --set hello.text="Hello whales!"
|
|
version: "3.6"
|
|
services:
|
|
hello:
|
|
command:
|
|
- -text
|
|
- Hello whales!
|
|
image: hashicorp/http-echo
|
|
ports:
|
|
- mode: ingress
|
|
target: 5678
|
|
published: 8080
|
|
protocol: tcp
|
|
```
|
|
|
|
Use `docker-compose up` to deploy the app.
|
|
|
|
```
|
|
$ docker-compose up --detach
|
|
WARNING: The Docker Engine you're using is running in swarm mode.
|
|
<Snip>
|
|
```
|
|
|
|
The application is now running as a Docker Compose app and should be reachable on port `8080` on your Docker host.
|
|
You must ensure traffic to port `8080` is allowed on the connection form your browser to your Docker host.
|
|
|
|
You can use `docker-compose down` to stop and remove the application.
|
|
|
|
#### Deploy as a Docker Stack
|
|
|
|
Deploying the app as a Docker stack is a two-step process very similar to deploying it as a Docker Compose app.
|
|
|
|
1. Render the Docker app project as a `docker-compose.yml` file.
|
|
2. Deploy the app using `docker stack deploy`.
|
|
|
|
Complete the steps in the previous section to render the Docker app project as a Compose file and make sure
|
|
you're ready to deploy it as a Docker Stack. Your Docker host must be in Swarm mode.
|
|
|
|
```
|
|
$ docker stack deploy hello-world-app -c docker-compose.yml
|
|
Creating network hello-world-app_default
|
|
Creating service hello-world-app_hello
|
|
```
|
|
|
|
The app is now deployed as a Docker stack and can be reached on port `8080` on your Docker host.
|
|
|
|
Use the `docker stack rm hello-world-app` command to stop and remove the stack. You must ensure traffic to
|
|
port `8080` is allowed on the connection form your browser to your Docker host.
|
|
|
|
### Push the app to Docker Hub
|
|
|
|
As mentioned in the introduction, `docker app` lets you manage entire
|
|
applications the same way that you currently manage container images. For
|
|
example, you can push and pull entire applications from registries like Docker
|
|
Hub with `docker app push` and `docker app pull`. Other `docker app` commands,
|
|
such as `install`, `upgrade`, `inspect`, and `render` can be performed directly
|
|
on applications while they are stored in a registry.
|
|
|
|
Push the application to Docker Hub. To complete this step, you need a valid
|
|
Docker ID and you must be logged in to the registry to which you are pushing
|
|
the app.
|
|
|
|
By default, all platform architectures are pushed to the registry. If you are
|
|
pushing an official Docker image as part of your app, you may find your app
|
|
bundle becomes large with all image architectures embedded. To just push the
|
|
architecture required, you can add the `--platform` flag.
|
|
|
|
```bash
|
|
$ docker login
|
|
|
|
$ docker app push my-app --platform="linux/amd64" --tag <hub-id>/<repo>:0.1.0
|
|
```
|
|
|
|
### Install the app directly from Docker Hub
|
|
|
|
Now that the app is pushed to the registry, try an `inspect` and `install` command against it.
|
|
The location of your app is different from the one provided in the examples.
|
|
|
|
```
|
|
$ docker app inspect myuser/hello-world:0.1.0
|
|
hello-world 0.1.0
|
|
|
|
Service (1) Replicas Ports Image
|
|
----------- -------- ----- -----
|
|
hello 1 8080 myuser/hello-world@sha256:ba27d460cd1f22a1a4331bdf74f4fccbc025552357e8a3249c40ae216275de96
|
|
|
|
Parameters (2) Value
|
|
-------------- -----
|
|
hello.port 8080
|
|
hello.text Hello world!
|
|
```
|
|
|
|
This action was performed directly against the app in the registry.
|
|
|
|
Now install it as a native Docker App by referencing the app in the registry, with a different port.
|
|
|
|
```
|
|
$ docker app install myuser/hello-world:0.1.0 --set hello.port=8181
|
|
Creating network hello-world_default
|
|
Creating service hello-world_hello
|
|
Application "hello-world" installed on context "default"
|
|
```
|
|
|
|
Test that the app is working.
|
|
|
|
The app used in these examples is a simple web server that displays the text "Hello world!" on port 8181,
|
|
your app might be different.
|
|
|
|
```
|
|
$ curl http://localhost:8181
|
|
Hello world!
|
|
```
|
|
|
|
Uninstall the app.
|
|
|
|
```
|
|
$ docker app uninstall hello-world
|
|
Removing service hello-world_hello
|
|
Removing network hello-world_default
|
|
Application "hello-world" uninstalled on context "default"
|
|
```
|
|
|
|
You can see the name of your Docker App with the `docker stack ls` command.
|