The following tutorial shows how to package the different APIs into microservice containers. The task at hand also could be achieved with Docker Compose (or Docker Swarm or Kubernetes), however the purpose of this tutorial is to provide a glimpse on the basics.
We will use a common, dedicated network for all services:
docker network create service_netThe Mongo database is also encapsulated in a docker container:
docker create -v ~/data:/data/db -p 27017:27017 --net service_net --name mongo mongo
docker start mongoCreate a base image with the common code used for this tutorial:
docker build -t tutorial-base .Creat a central folder for the logs from all services (make sure that ):
mkdir logsfor n in $(ls -d ./containers/*/); do s=${n#./containers/}; docker build -t ${s%/} ${n}; doneThe command above it is the equivalent of issuing the following command 4 times with different service names, where the inventory is the name of one service:
docker build -t inventory ./containers/inventoryBuild and run the Inventory Service:
docker run --name inventory -d -v $(pwd)/logs:/logs -p 5001:5000 --net service_net inventory
Build and run the Order Service:
docker run --name orders -d -v $(pwd)/logs:/logs -p 5000:5000 --net service_net ordersBuild and run the Payments Service:
docker run --name payments -d -v $(pwd)/logs:/logs -p 5002:5000 --net service_net paymentsBuild and run the Shipping Service:
docker run --name shipping -d -v $(pwd)/logs:/logs -p 5003:5000 --net service_net shippingdocker psThe expected output is:
ONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
022bd90ce981 shipping "python service.py" 35 seconds ago Up 35 seconds 5003/tcp, 0.0.0.0:5003->5000/tcp shipping
e77e06aca71f payments "python service.py" 41 seconds ago Up 40 seconds 5002/tcp, 0.0.0.0:5002->5000/tcp payments
194897a60688 orders "python service.py" 47 seconds ago Up 46 seconds 0.0.0.0:5000->5000/tcp orders
60d4c511b383 inventory "python service.py" About a minute ago Up About a minute 5001/tcp, 0.0.0.0:5001->5000/tcp inventory
6c897f1c41d0 mongo "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:27017->27017/tcp mongoYou also should be able to see the log files for each service:
ls -a ./logs
. .. inventory.log orders.log payments.log shipping.logYou can tail it in one terminal window right away:
tail -fn 300 ./logs/orders.log
2018-09-16 13:45:46,690 - INFO - flask.app:360 - Logger initialised
2018-09-16 13:45:46,698 - INFO - flask.app:249 - ===== Starting Order Service =====
2018-09-16 13:45:46,699 - DEBUG - flask.app:250 - --> registered routes:
Map([<Rule '/orders/aggregate/' (HEAD, GET, OPTIONS) -> orders_aggregate_get>,
<Rule '/orders/schema' (HEAD, GET, OPTIONS) -> orders_schema_get>,
<Rule '/orders/meta' (HEAD, GET, OPTIONS) -> orders_meta_get>,
<Rule '/orders/' (HEAD, GET, OPTIONS) -> orders_find_by_query_get>,
<Rule '/orders/' (PUT, OPTIONS) -> orders_replace_object_put>,
<Rule '/orders/' (POST, OPTIONS) -> orders_save_object_post>,
<Rule '/orders/<object_id>' (DELETE, OPTIONS) -> orders_delete_by_id_delete>,
<Rule '/orders/<object_id>' (HEAD, GET, OPTIONS) -> orders_find_by_id_get>,
<Rule '/orders/<object_id>' (PATCH, OPTIONS) -> orders_save_object_patch>,
<Rule '/static/<filename>' (HEAD, GET, OPTIONS) -> static>])curl -i -X POST \
-H "Content-Type:application/json" \
-d \
'{
"_type": "tutorials.order_service.Order",
"delivery_address": {
"_type": "tutorials.models.Address",
"city": "Big City",
"country": "Country",
"first_name": "John",
"last_name": "Doe",
"postal_code": "1234",
"street": "some address 8"
},
"id": "Oc2e5b438-8d12-4533-b085-c38add1e126d",
"order_date": "2018-09-04T18:51:18.547186",
"payment_method": {
"_type": "tutorials.models.Payment",
"customer_id": "1234567890123456789012",
"customer_secret": "120",
"method": "PAYPAL"
},
"products": [
{
"_type": "tests.test_util.Product",
"code": "BTX",
"name": "t-shirt",
"price": {
"_type": "money.money.Money",
"amount": 10,
"currency": "EUR"
},
"size": "M"
},
{
"_type": "tests.test_util.Product",
"code": "BTX",
"name": "t-shirt",
"price": {
"_type": "money.money.Money",
"amount": 12,
"currency": "EUR"
},
"size": "L"
}
]
}
' \
'http://localhost:5000/orders/'After having fun with the little setup and you'd like to clean up the place, just follow the steps bellow:
for n in $(ls -d ./containers/*/); do s=$(echo ${n}|cut -d/ -f3); docker stop ${s}; docker rm ${s}; docker rmi ${s}; doneThe code from above is the
docker stop shipping payments inventory orders
docker rm shipping payments inventory orders
docker rmi shipping payments inventory ordersYou might also want to delete the log files:
rm ./logs/*