docs/app/working-with-app.md

14 KiB

title description keywords
Working with Docker App Learn about Docker App Docker App, applications, compose, orchestration

Overview

Docker App is a CLI plug-in that introduces a top-level docker app command that brings the container experience to applications. The following table compares Docker containers with Docker applications.

Object Config file Build with Execute with
Container Dockerfile docker image build docker container run
App bundle.json docker app bundle docker app install

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.

This guide will walk you through two scenarios:

  1. Initialize and deploy a new Docker App project from scratch
  2. Convert an existing Compose app into a Docker App project (Added later in the beta process)

The first scenario will familiarize you with the basic components of a Docker App and get you comfortable with the tools and workflow.

Initialize and deploy a new Docker App project from scratch

In this section, we'll walk through the process of creating a new Docker App project. By then end, you'll be familiar with the workflow and most important commands.

We'll complete the following steps:

  1. Pre-requisites
  2. Initialize an empty new project
  3. Populate the project
  4. Validate the app
  5. Deploy the app
  6. Push the app to Docker Hub
  7. Install the app directly from Docker Hub

Pre-requisites

In order to follow along, you'll need at least one Docker node operating in Swarm mode. You will 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 may 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 will produce a single file in your current directory called hello-world.dockerapp. The format of the file name is appended with .dockerapp.

$ ls
hello-world.dockerapp

If you run docker app init without the --single-file flag you will get a new directory containing three YAML files. The name of the directory will the name of the project with .dockerapp appended, and the three YAML files will be:

  • 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 above --- docker-compose.yml, metadata.yml, and parameters.yml. Using the --single-file option is great for enabling you to share your application via 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 may 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 is where you specify identification metadata such as name, version, and description. 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 is where default values for application parameters can be expressed. It can be a separate file called parameters.yml

Populate the project

In this section, we'll edit the project YAML file so that it runs a simple web app.

Use your preferred editor to edit the hello-world.dockerapp YMAL file and update the application section to the following:

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

Update the Parameters section to the following:

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 has been updated to run a single-container application based on the hashicorp/http-echo web server image. This image will have it execute a single command that displays some text and exposes itself on a network port.

Following best-practices, the configuration of the application has been decoupled form the application itself using variables. In this case, the text displayed by the app, and the port it will be published on, are controlled by two variables defined in the Parameters section of the file.

Docker App provides the inspect sub-command to provide a prettified summary of the application configuration. 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
-------------- -----
port           8080
text           Hello world!

docker app inspect operations will fail if the parameters section doesn't specify a default value for every parameter expressed in the app section.

The application is ready to validated and rendered.

Validate the app

Docker App provides the validate sub-command to check syntax and other aspects of the configuration. If validation passes, the command returns no arguments.

$ docker app validate hello-world.dockerapp
Validated "hello-world.dockerapp"

docker app validate operations will 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.

  1. Deploy as a native Docker App application
  2. Deploy as a Compose app application
  3. Deploy as a Docker Stack application

We'll look at all three options, starting with deploying as a native Dock App application.

Deploy as a native Docker App

The process for deploying as a native Docker app is as follows.

  1. 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

The app will be deployed using the stack orchestrator. This means you can inspect it with regular docker stack commands.

$ docker stack ls
NAME                SERVICES            ORCHESTRATOR
my-app              1                   Swarm

You can also check the status of the app with the docker app status <app-name> command.

$ docker app status my-app
ID              NAME            MODE          REPLICAS    IMAGE             PORTS
miqdk1v7j3zk    my-app_hello    replicated    1/1         hashicorp/http-echo:latest   *:8080->5678/tcp

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 in all its glory. You will need to ensure traffic to port 8080 is allowed on the connection form your browser to your Docker host.

You can uninstall the app with docker app uninstall my-app.

Deploy as a Docker Compose app

The process for deploying a 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 will need a recent version of Docker Compose tom complete these steps.

Rendering is the process of reading the entire application configuration and outputting it as a single docker-compose.yml file. This will create 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, ${text} has been expanded to "Hello world!".

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 will need to 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.

We'll assume that you've followed the steps to render the Docker app project as a compose file (shown in the previous section) and that you're ready to deploy it as a Docker Stack. Your Docker host will need to 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 will need to 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 intro, docker app lets you manage entire applications the same way that we 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, and render can be performed directly on applications while they are stored in a registry.

Let's see some examples.

Push the application to Docker Hub. To complete this step, you'll need a valid Docker ID and you'll need to be logged in to the registry you are pushing the app to.

Be sure to replace the registry ID in the example below with your own.

$ docker app push my-app --tag nigelpoulton/app-test:0.1.0
docker app push hello-world.dockerapp --tag nigelpoulton/app-test:0.1.0
docker.io/nigelpoulton/app-test:0.1.0-invoc
hashicorp/http-echo
 application/vnd.docker.distribution.manifest.v2+json [2/2] (sha256:ba27d460...)
<Snip>

The app is now stored in the container registry.

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 will be different to the one shown in the examples.

$ docker app inspect nigelpoulton/app-test:0.1.0
hello-world 0.1.0

Service (1) Replicas Ports Image
----------- -------- ----- -----
hello       1        8080  nigelpoulton/app-test@sha256:ba27d460cd1f22a1a4331bdf74f4fccbc025552357e8a3249c40ae216275de96

Parameters (2) Value
-------------- -----
port           8080
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.

$ docker app install nigelpoulton/app-test:0.1.0
Creating network hello-world_default
Creating service hello-world_hello

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 8080, your app may be different.

$ curl http://localhost:8080
Hello world!

Uninstall the app.

$ docker app uninstall hello-world
Removing service hello-world_hello
Removing network hello-world_default

You can see the name of your Docker App with the docker stack ls command.

Convert an existing Compose app into a Docker App project

Content TBA