- 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=
- 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
- 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
- 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.
- 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":[]}
- 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"]}
- 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"}
- 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!
- 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
- Try to request,
curl -POST -F [email protected] http://ec2.compute.amazonaws.com
# replace with your actual EC2 ip