How to Create a Docker Image for Lisky

And Send Lisky Commands to Lisk Testnet using a Command Line Script

What You Will Learn

A basic introduction to Docker concepts.

An introduction to the Dockerfile.

How to build a Docker image from a Dockerfile using the build command.

command. How to start a Docker container from a Docker image using the run command and use the container interactively.

command and use the container interactively. How to run basic Lisky commands.

How to send commands to running containers using Docker exec .

Reading Audience:

You are interested in the Lisk.io blockchain technology and in testing apps from the LiskHQ repositories.

You are familiar with executing commands from the command line.

You should install Docker on your computer and run the demonstrated commands to get the most benefit out of this tutorial.

Throughout this article I will be showing the command line output from various commands captured by an application called asciinema. You don’t have to install any software to use it. To show the output, just right-click on the terminal window and open a new window. You can then watch it on the asciinema website like most any other video on the web.

What is Docker?

Docker is a software tool for building, running and managing virtual application instances called containers. If you are interested, the following youtube.com video provides more information about Docker and containers. However, you will see Docker in action in the rest of the article.

What is Docker?

(3:02 minutes) This video gives an introductory explanation of the difference between virtual machines and Docker containers and why containers are useful for developers.

From www.docker.com/what-container

“A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings for Linux, MacOSX and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.”

What is a Docker Repository?

Docker keeps a local list, or a repository, of images built with Docker on our computer. Let’s run a command to list the images in our local repository.

john@ragnarok:~$ docker image ls

REPOSITORY TAG IMAGE ID CREATED SIZE

john@ragnarok:~$

My local image repository is empty. Your local repository may have some images in it after installing Docker. For this article, we need to make a new Docker image for Lisky in our repository.

The Public Lisk HQ Docker Repository

LiskHQ has setup a public repository of Lisk images at hub.docker.com/u/lisk/. It has Docker images for mainnet, testnet, explorer and faucet. However, there is no Docker image for Lisky. I want to build a Docker image for Lisky so that I can launch a Lisky container and send commands from it to the Testnet network.

The Lisky installation page says Node.js is required to install Lisky. Since we are using Docker, we don’t actually need to install Node.js on our computer. There are official Docker images for Node.js that we will use instead to build a Docker image for Lisky.

How to Build a Docker Image with a Dockerfile

To build a Docker image, we need to make a text file named Dockerfile . A Dockerfile is like a recipe that tells Docker how to build an image by gathering required components and following instructions.

Here is my Dockerfile for building a Lisky image.

FROM node

RUN npm install --global --production lisky

My Dockerfile for building a Lisky image has two lines. Pretty simple, right?

There are some other entries I could have put in the Dockerfile to make the image more useful, but for now, this will meet my current needs for simple testing. Once the image is built, it can be launched as a container for the Lisky application running inside of it.

What are the commands in the Dockerfile doing?

First, the Dockerfile tells Docker to run the command FROM node , which pulls the image node:latest from the public Docker repository and puts it in my local repository.

The Lisky installation page also states we need to run the command RUN npm install --global --production lisky . This tells Docker to install Lisky inside the node:latest image in my local repository.

Build the Lisky Docker Image

Now that we have the Dockerfile to build the Lisky image we can run the build command. The command will take a minute or so to download and extract the files needed for the build. First, I’ll show you the build command’s syntax.

docker build --rm --tag lisky:node . docker The base command for the Docker CLI.

build Build an image from a Dockerfile.

--rm Remove intermediate containers after a successful build (default true).

--tag Name and optionally a tag in the 'name:tag' format ("lisky:node").

. The build context directory containing the Dockerfile and other files that may be needed for the build. (The "." represents the current directory.)

Click on the big arrow to see the captured output from running the docker build --rm --tag lisky:node . command. The length of the captured output is 2:18 seconds, but you can forward the output with your mouse.

Right-click on the arrow and open a new window to see the results of the test.

Let’s check our local repository.

john@ragnarok:~/projects/docker/lisky-node$ docker image ls

REPOSITORY TAG IMAGE ID CREATED SIZE

lisky node 351c7a113c7d 39 minutes ago 696MB

node latest ec70562ad6f0 2 days ago 673MB

john@ragnarok:~/projects/docker/lisky-node$

The 673MB image node:latest was pulled to my local repository from the public Docker Hub repository in order to build my 696MB Docker image tagged lisky:node. The image node:latest has many Linux commands in it which would be helpful if we wanted to do something more than just running Lisky during development and testing.

How to Run the Lisky Container

Now that we have a new image, we can start its container and test it.

Here is an explanation of the command:

docker run --tty --interactive --rm lisky:node lisky docker The base command for the Docker CLI.

run Run a command in a new container

--tty Start a pseudo tty terminal. It is _not_ the same as the "tag" option for "docker build"

--interactive Run in interactive mode.

--rm Automatically remove the container from memory when it exits.

lisky:node The tagged Docker image to be started.

lisky Run the command "lisky" inside the container after it is launched.

When Lisky starts I’ll run the Lisky command config to test it.

Right-click on the arrow and open a new window to see the results of the test.

It works! We can now push the image to hub.docker.com and pull the lisky:node image to any other Linux, Microsoft Windows or MacOSX computer that has Docker installed and they will all run the Lisky Docker image successfully.

If you want to run more Lisky commands, see lisk.io/documentation/lisk-commander/usage/commands and re-run the command docker run --tty --interactive --rm lisky:node lisky . But don’t get too distracted! We still have some more interesting items to cover in this tutorial.

Let’s Build a Smaller Lisky Image

I want to build a smaller and simpler Lisky image if I am going to run many Lisky containers to simulate lots of users in a Lisk network. Fortunately, the Docker Hub also has a node:alpine image which is ~5MB!

Here is my Dockerfile for building a much smaller Lisky image.

john@ragnarok:~/projects/docker/lisky.alpine$ cat Dockerfile

FROM node:alpine

RUN apk --no-cache add git

RUN npm install --global --production lisky

Lisky requires the git command which is missing in node:alpine. That is why I have RUN apk --no-cache add git in my Dockerfile to install git.

We already know how the following ‘docker build’ command works. Here is the captured output.

Right-click on the arrow and a new window to see the results of the test.

How small is our new Lisky image?

Now let’s check the size of the Lisky image built on top of the small node:alpine image.

john@ragnarok:~/projects/docker/lisky-alpine$ docker image ls

REPOSITORY TAG IMAGE ID CREATED SIZE

lisky alpine 67b0d1b804fb 8 minutes ago 113MB

lisky node 351c7a113c7d About an hour ago 696MB

node alpine 4a6857f6f75d 2 days ago 68.4MB

node latest ec70562ad6f0 2 days ago 673MB

john@ragnarok:~/projects/docker/lisky-alpine$

Our new Docker Lisky image is 113MB. We have decreased the size of our Lisky image by 84%!

Testing Our Small Lisky Image

Let’s test our new lisky:alpine image by starting the container in interactive mode. We will then run some test commands:

set pretty true to make the output easier to read. set testnet true to send Lisky commands to Testnet. config to show our new Lisky configuration. get transaction 16138217535681461985 . I found that transaction ID on https://testnet-explorer.lisk.io/. (try other values for extra credit :D ) exit to exit Lisky.

Here are the results of the test.

Right-click on the arrow and open a new window to see the results of the test.

Like the test we did with the 700MB image lisk:node, we know it works.

But what if I want to automate sending commands to this Lisky container, such as in a script? Luckily, there is a docker exec --interactive --detach CONTAINER COMMAND that lets us do just that.

docker The base command for the Docker CLI.

exec Run a command in a running container.

--interactive Keep STDIN open even if not attached.

--detach Detached mode: run command in the background.

CONTAINER Assigned name of the container.

COMMAND The command sent from our command line to the running container.

First, we need to start the container in interactive mode and run the container in the background. Then we will run docker ps to get the friendly name of the container.

john@ragnarok:~/projects/docker/lisky-alpine$ docker run --interactive --detach lisky:alpine

23c7803dddc1f2b64bfc055b703fe304674245f0153d3668241bf47d9bb66006

john@ragnarok:~/projects/docker/lisky-alpine$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

23c7803dddc1 lisky:alpine "node" 4 seconds ago Up 2 seconds relaxed_mcnulty

john@ragnarok:~/projects/docker/lisky-alpine$

Now that we have the assigned container’s friendly name, “relaxed_mcnulty”, we can send commands directly from the command line, or from a script, to it.

Here is my test script:

john@ragnarok:~/projects/docker/lisky-alpine$ cat sendcmdstoLisky.sh

echo "set json true"

docker exec --interactive relaxed_mcnulty /usr/local/bin/lisky set json true

echo "set pretty true"

docker exec --interactive relaxed_mcnulty /usr/local/bin/lisky set pretty true

echo "set testnet true"

docker exec --interactive relaxed_mcnulty /usr/local/bin/lisky set testnet true

echo "get address 6076671634347365051L"

docker exec --interactive relaxed_mcnulty /usr/local/bin/lisky get address 6076671634347365051L

And here are the results.

Right-click on the arrow and open a new window to see the results of the test.

Let’s review what we have learned.

A basic introduction to Docker concepts.

A Dockerfile is a recipe for building an image. If you want to learn more, here is a good tutorial for writing Dockerfiles: www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/ .

How to build a Docker image from a Dockerfile. docker build --tag lisky:alpine .

How to start a Docker container from a Docker image and use it interactively. docker run --interactive --tty --rm lisky:alpine lisky

How to run basic Lisky commands. For more commands, see lisk.io/documentation/lisk-commander/usage.

How to send commands to running containers using docker exec --interactive container command .

Hope you enjoyed this article as much as I enjoyed researching and writing it!

You can find the Docker images created for Lisky in this article at hub.docker.com/r/johnalexhebert/lisky/.

Next Article: A Network of Lisk Nodes and Lisky Clients Using Docker Containers

My next article will cover creating an isolated Docker network of Lisk Core nodes and launching multiple Docker Lisky containers inside of it for development and testing.

Questions and Suggestions:

johnalexhebert@gmail.com

twitter: John Hebert