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
- How to start a Docker container from a Docker image using the
runcommand and use the container interactively.
- How to run basic Lisky commands.
- How to send commands to running containers using Docker
- 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 are .webm files that show the command line output from various Docker commands captured by an application called asciinema. Check it out, it is very useful for adding live examples to documentation!
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.
- “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.
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.
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.
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 trueto make the output easier to read.
set testnet trueto send Lisky commands to Testnet.
configto 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 😀 )
exitto exit Lisky.
Here are 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.
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:
twitter: John Hebert