Docker usage in Blockchain project

Docker is the single most important tool when developing blockchain applications.

Why?

When you are developing blockchain applications,

1. you are creating a distributed application, locally

2. you need automation to reduce the time spent on error-prone steps involved in deploying and testing

3. you want to test your application with real users as soon as possible!

These factors, and many more, make Docker an invaluable tool in your toolkit. Not only is Docker a tool to ease your development, it also enables and encourages a different way of working — a way of working which lowers technical debt and increases agility (the reaction speed to changing environments).

What is Docker?

Docker

 is a container platform — much like the containers found on container ships — which enables the creation, shipment and deployment of small, self-contained, software components. These components can then be combined to create a service offering (SaaS), web or mobile application (app), or distributed blockchain application (dApp).

The Docker engine (Community Edition or CE) is free of use and runs on nearly every platform. Installing it is easy, just download and run the installer found on the Docker docs page. Once it is installed, creating and running Docker containers is just a matter of entering ‘docker run <image>’ from the command line, where <image> is the name of the image published on the Docker Hub. A private image can also be run, by prepending the image name with the name of the private or local hub.

How can I create my own Docker Image?

After installing Docker and running the ‘hello world’ example, it is time to create your first image and run it. Before you alt-tab out of here: this is easier than it sounds! All you need, is a single text-file called ‘Dockerfile’. These are the steps to follow:

  1. Create a new folder, called ‘my-first-docker-image’ for example.
  2. Create a file in this folder, called ‘Dockerfile’ (exact naming, no extension)
  3. Open this file, and enter the following 2 lines of text:
FROM python:2
CMD [ "python","-c", "print '\\n'.join(\"%i Byte = %i Bit = largest number: %i\" % (j, j*8, 256**j-1) for j in (1 << i for i in xrange(8)))" ]

4. Save & close the file, then execute docker build -t python-test .

5. After a while (some base images will be downloaded), your image is built and ready to use! Enter the following command to get it up and running: docker run -it --rm python-test

The output should be:

1 Byte = 8 Bit = largest number: 255
2 Byte = 16 Bit = largest number: 65535
4 Byte = 32 Bit = largest number: 4294967295
(...)

Even without any version of python installed on your local machine (this command itself also does not install python), the script is executed and its result shown in your terminal.

Some explanation of the commands used in these steps:

docker = The keyword to execute docker-related commands

docker build = Builds new docker images. You can give them a name (python-test in our example) with the -t option and it requires a path to the Dockerfile ( . in our example)

docker run = Runs docker images. You can use -it to attach an (interactive) terminal to the docker container and --rm to automatically remove the container when it finishes. An identifier for the image to run is required (again python-test in our example).

How do I speed up blockchain application development using Docker?

So now we have Docker installed and can download, build and run docker containers, we are ready for the next step: speeding up blockchain application development using Docker.

First up, it is important to see that there are 3 distinct components that interact in a basic blockchain application, namely:

  • A web interface (we’ll use Vue from https://vuejs.org/)
  • Smart contracts + tests and deployment (we’ll use the Truffle framework from http://truffleframework.com/)
  • An Ethereum node, a test-node for now (we’ll use ganache-cli, also from the Truffle framework)

These 3 components are a perfect fit for independent Docker containers, so let’s get started!

Step 1: NPM init

First, create a new folder for this project. I’ve called it minimal-blockchain-docker, but you’re free to be more creative of course.

Then run npm init in this folder and just go with all the default answers.

Step 2: Creating the UI using Vue

Create a services folder and navigate to it using the command line, install the Vue CLI (https://github.com/vuejs/vue-cli) if you haven’t done so yet and initialise the web interface:

npm install -g @vue/cli
# or
yarn global add @vue/cli

vue create ui

The output should look like the following snippet:

(…)
Successfully created project ui.
Get started with the following commands:
$ cd ui
$ yarn serve

You can do this, if you want to check if the standard Vue page gets hosted correctly and works out of the box. (it should!)

We now have a working UI component. Yay!

Step 3: Create some smart contracts

Let’s get working on thew smart contracts now, it’s the heart of our blockchain application!

First, go back to the services folder, and create a smart-contracts subfolder in which we init a basic Truffle project (after installing Truffle, if we haven’t done so yet):

npm install -g truffle

mkdir smart-contracts
cd smart-contracts
truffle unbox metacoin

There we go, we now have a boilerplate smart contract in solidity, ready to compile and run!

The compilation of the contract we can already do by executing truffle compile . At the time of writing, this gives some deprecation warnings on the boilerplate code, but it does compile (which is good!).

To actually run the code, we also need a testing environment to run this on… so let’s create one!

Step 4: Install and run Ganache-CLI

This one is a bit different from the other two components: we are just going to run it out of the box (kinda).

What is Ganache-CLI? (https://github.com/trufflesuite/ganache-cli) It’s a test framework on which we can deploy our smart contracts and use to test our blockchain application. Installation and running it is straightforward:

npm install -g ganache-cli
ganache-cli

So, once this is running you can then

  • “Migrate” the smart contracts, and,
  • Start the UI

However, if you change a smart contract — it is required to restart ganache-cli, compile and migrate the solidity contracts and restart the UI (if needed). That’s a hassle?! Also — if you host this software somewhere or want to run it on a different machine for any reason, you have to go through all these steps again.

We can do better than this!

Step 5: Putting it all together in a single docker-compose file

Docker-compose (https://docs.docker.com/compose/) is a tool for running multi-container Docker applications.

Having each component “Dockerized”, we can now put it together in a docker-compose.yml file. In docker-compose files, one defines different services, and their dependencies and interactions. For the previously mentioned docker images, our docker-compose.yml file looks like this:

version: ‘3’

services:
 # gateway/reverse proxy
 nginx:
  build: ./services/nginx
  restart: always
  depends_on:
   - api
   - ui
   - ganache
  volumes:
   - ./logs:/var/log/nginx
  ports:
   # proxy api + ui
   - “80:9000”
   # proxy ethereum node so you can connect with metamask from browser
   - “8545:9001”

 # starts webpack watch server with hot reload for ui (vue) code
 ui:
  build:
   context: ./services/ui
   dockerfile: Dockerfile.development
  restart: always
  env_file:
   - ./services/ui/.env
  volumes:
   - ./services/ui/src:/app/ui/src/
   - ./logs:/logs

 # api, handles browser requests initiated from ui api:
 api:
  build:
   context: ./services/api
   dockerfile: Dockerfile.development
  restart: always
  env_file:
   - ./services/api/.env
  depends_on:
   - mongo
  volumes:
   - ./services/api/src:/app/api/src/
   - ./logs:/logs

 # smart contracts source, tests and deployment code
 smart-contracts:
  build:
   context: ./services/smart-contracts
   dockerfile: Dockerfile.development
  env_file:
   - ./services/smart-contracts/.env
  depends_on:
   - ganache
  volumes:
   # mount the output contract build files into a host folder
   - ./services/smart-contracts/src/build:/app/smart-contracts/build/
   # mount the output test coverage report folder into a host folder
   - ./services/smart-contracts/coverage-report:/app/smart-contracts/coverage/
   - ./logs:/logs

 # ganache-cli ethereum node
 ganache:
  image: trufflesuite/ganache-cli
  command: “–seed abcd --defaultBalanceEther 100000000”

 # mongodb
 mongo:
  build: ./services/mongodb
  restart: always
  ports:
   # allow acces from (only!) localhost to mongo port 27017 so you can use
   # MongoHub or some other app to connect to the mongodb and view its contents
   - “127.0.0.1:27017:27017”
  volumes:
   - ./data/mongo:/data/db
   - ./logs:/var/log/mongodb

Tip: this file is also accessible in our Github pagedocker-compose.yml

Building and starting these docker images is as simple as running docker-compose up . Try it! 

Tip: to hide all the output, you can use the -d flag, after which you can check the separate logs with docker logs xxx where xxx is the name of the instance.

This fixes us having to start all the containers ourselves, but we still need to find a way to automate the building and deployment of the solidity smart contracts. For this, we use the NPM scripting language:

(…)
“start”: “npm run deploy:smart-contracts && docker-compose up --build nginx api ui ganache mongo”,
(…)

Tip: All of the scripts are in the package.json file in our Github repository.

This can be started with the npm run start command! The single command needed to start the boilerplate. Stopping the boilerplate is also simple, by using the npm run stop command. (yarn start and yarn stop also work)

All changes made to the code will automatically reflect in the running dApp due to shared folders

That’s it, we’ve automated pretty much everything to get this running on your laptop (or any other laptop or VM). So…

End…

Well, next step is to get this into production and monitor the running dApps.

Next blog we will get into how we can run these containers (and the smart contracts) on a Kubernetes cluster!

If you spot any errors, or have any suggestions on improvements: please leave either a comment here, or at the Github page. Also, if you liked this post — don’t forget to clap and share it with all of your programming buddies!

Further reading

Building a Blockchain with Python - Full

☞ Learn Python by Building a Blockchain & Cryptocurrency

A Beginners Guide to Blockchain Technology

☞ Blockchain and Bitcoin Fundamentals

☞ Blockchain A-Z™: Learn How To Build Your First Blockchain

Create a Blockchain Explorer in Csharp

Build a simple Cryptocurrency App using Angular 8

#docker #blockchain #cryptocurrency #solidity #bitcoin

Docker usage in Blockchain project
2 Likes37.20 GEEK