Docker Hello world application


Example

Usually you'd want to create a stack of services to form a replicated and orchestrated application.

A typical modern web application consists of a database, api, frontend and reverse proxy.

Persistence

Database needs persistence, so we need some filesystem which is shared across all the nodes in a swarm. It can be NAS, NFS server, GFS2 or anything else. Setting it up is out of scope here. Currently Docker doesn't contain and doesn't manage persistence in a swarm. This example assumes that there's /nfs/ shared location mounted across all nodes.

Network

To be able to communicate with each other, services in a swarm need to be on the same network.

Choose an IP range (here 10.0.9.0/24) and network name (hello-network) and run a command:

docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  --opt encrypted \
  hello-network

Database

The first service we need is a database. Let's use postgresql as an example. Create a folder for a database in nfs/postgres and run this:

docker service create --replicas 1 --name hello-db \
       --network hello-network -e PGDATA=/var/lib/postgresql/data \
       --mount type=bind,src=/nfs/postgres,dst=/var/lib/postgresql/data \
       kiasaki/alpine-postgres:9.5

Notice that we've used --network hello-network and --mount options.

API

Creating API is out of scope of this example, so let's pretend you have an API image under username/hello-api.

docker service create --replicas 1 --name hello-api \
       --network hello-network \
       -e NODE_ENV=production -e PORT=80 -e POSTGRESQL_HOST=hello-db \
       username/hello-api

Notice that we passed a name of our database service. Docker swarm has an embedded round-robin DNS server, so API will be able to connect to database by using its DNS name.

Reverse proxy

Let's create nginx service to serve our API to an outer world. Create nginx config files in a shared location and run this:

docker service create --replicas 1 --name hello-load-balancer \
       --network hello-network \
       --mount type=bind,src=/nfs/nginx/nginx.conf,dst=/etc/nginx/nginx.conf \
       -p 80:80 \
       nginx:1.10-alpine

Notice that we've used -p option to publish a port. This port would be available to any node in a swarm.