Skip to content

Latest commit

 

History

History
 
 

11.inception-docker-swarm-nginx

How-to

  1. Make sure you installed Docker-machine and registered AWS account.
env
# make sure you have AWS_SECRET_ACCESS_KEY=
# make sure you have AWS_ACCESS_KEY_ID=
  1. Create 3 EC2 VPS. I live in Malaysia, so I spawned them at Singapore. You can check supported regions here.
docker-machine create --driver amazonec2 --amazonec2-region ap-southeast-1 tf-master
docker-machine create --driver amazonec2 --amazonec2-region ap-southeast-1 tf-node-1
docker-machine create --driver amazonec2 --amazonec2-region ap-southeast-1 tf-node-2
  1. SSH our master tf-master and install docker-compose,
docker-machine ssh tf-master
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
  1. Init the swarm,
sudo docker swarm init

You can see it will returned, docker swarm join --token, paste this to your all nodes. tf-node-1, tf-node-2.

docker-machine ssh tf-node-1
sudo docker swarm join --token

Repeat above for all your nodes.

  1. Spawn Docker-Registry in your master,

Create /etc/docker/daemon.json in all our master and nodes,

{ "insecure-registries":["your-ip:5000"] }

Restart docker,

sudo service docker restart

Spawn Docker-Registry,

sudo docker service create --name registry --publish published=5000,target=5000 registry:2

Go get your Public DNS inside EC2 Panel and curl like this,

curl http://ec2.ap-southeast-1.compute.amazonaws.com:5000/v2/_catalog
{"repositories":[]}
  1. Build the image inside our local folder,
docker build .

and put tag on it, you required to get the IMAGE ID, in my case I got f80e2d883c9c

docker tag f80e2d883c9c ec2.ap-southeast-1.compute.amazonaws.com:5000/flask-inception
docker push ec2.ap-southeast-1.compute.amazonaws.com:5000/flask-inception

You can try to curl again,

curl http://ec2.ap-southeast-1.compute.amazonaws.com:5000/v2/_catalog
{"repositories":["flask-inception"]}
  1. Now create docker-compose.yml,
version: '3'

services:
  flask-inception:
    image: your-ip:5000/flask-inception
    ports:
      - "7000:7000"

You can try to run it,

sudo docker-compose -f docker-compose.yml up --build
flask-inception_1  |    WARNING: Do not use the development server in a production environment.
flask-inception_1  |    Use a production WSGI server instead.
flask-inception_1  |  * Debug mode: on
flask-inception_1  |  * Running on http://0.0.0.0:7000/ (Press CTRL+C to quit)
flask-inception_1  |  * Restarting with stat

Can try to curl it,

curl -POST -F [email protected] http://ec2.ap-southeast-1.compute.amazonaws.com:7000
{"label": "soft-coated wheaten terrier", "computer-name": "1f559338678b"}
  1. Spawn the stack,
sudo docker stack deploy --compose-file docker-compose.yml inception

Give few minutes, and try to request on our master and nodes,

curl -POST -F [email protected] http://master:7000
curl -POST -F [email protected] http://node1:7000
curl -POST -F [email protected] http://node2:7000

All of these should returned value.

Problem here, you want a single API point but has multiple back-ends on it, Nginx is our solution!

  1. Deploy Nginx as load-balancer,

kill our stack first,

sudo docker stack rm inception

Get IPs of our nodes and master,

for NODE in $(sudo docker node ls --format '{{.Hostname}}'); \
do echo -e "${NODE} - $(sudo docker node inspect --format '{{.Status.Addr}}' "${NODE}")"; done
tf-master - 172.31.40.167
tf-node-1 - 172.31.46.207
tf-node-2 - 172.31.36.4

Create a directory nginx,

mkdir nginx

Create a file load-balancer.conf,

events { worker_connections 1024; }

http {
	upstream backend {
   		server 172.31.40.167:7000;
   		server 172.31.46.207:7000;
   		server 172.31.36.4:7000;
	}

	server {
   		listen 80;

   		location / {
      			proxy_pass http://backend;
   		}

	}
}

Create a file Dockerfile,

FROM nginx
COPY load-balancer.conf /etc/nginx/nginx.conf

Build the image,

sudo docker build . -t nginx-inception

Now, back to folder where we put our docker-compose.yml and edit it,

version: '3'

services:
  flask-inception:
    image: 172.31.40.167:5000/flask-inception
    ports:
      - "7000:7000"

  nginx:
    image: nginx-inception
    ports:
     - "80:80"

Stack it!

sudo docker stack deploy --compose-file docker-compose.yml inception
  1. Try to request,
curl -POST -F [email protected] http://ec2.compute.amazonaws.com
# replace with your actual EC2 ip