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.