Visualizing containers with clarity
Port of Call
Sometimes a relatively small but crucial piece of information is enveloped in screeds of command-line output. Thankfully, you can sort the wheat from the chaff with complementary command-line tools, ideally those with some form of graphical display. Developer Liran Tal has been quietly working away on a very useful tool called Dockly that he describes as an "Immersive terminal interface for managing docker containers and services" [1]. If you have ever been responsible for a Docker host running multitudinous containers simultaneously, you're almost certainly aware of the complexity of herding numerous cat-like containers. In this article, I run through the installation of Dockly and look at the slick, lightweight tool in action.
Softly, Softly
To whet your appetite before proceeding, the Dockly website offers some animated examples of what to expect when beautifying your command line. Next, head over to the Dockly GitHub page [2], which contains examples of some of the Dockly command-line operations.
To install Dockly [3], you can choose one of two routes: with npm
(see the "Installation by npm" box for that route) and in a Docker container. For context, on my laptop, about 43MB of file space would be taken up by the npm packages (about 75), and although that's not a large amount of disk space, it is still lots of little packages with many lines of potentially insecure code. My rule of thumb is that if I can avoid adding packages, I will. Because the clever Dockly offers an alternative installation route in the form of a Docker container, I'll choose that every time.
Installation by npm
Installing Dockly with the npm
JavaScript package manager [4] is clear and straightforward. If npm
is not available on your local machine, you can install it with the command (for my Linux Mint 19 laptop running Ubuntu 18.04 under the bonnet):
$ apt install npm
Now you can install and run Dockly with the commands:
$ npm install -g dockly $ dockly
Incidentally, according to the docs, Dockly requires Node.js v7.6 and upward, so if you have trouble running the tool, try upgrading npm
, installing from source, if required.
Quietly Does It
For security reasons, I won't just blindly pull a Docker container from an image registry. Instead, I'll build my own container image after checking the supplied Dockerfile [5]. To begin, I clone the repository on GitHub and enter the directory (use apt install git
first if git
is not on your machine):
$ git clone https://github.com/lirantal/dockly.git $ cd dockly codefresh.yml Dockerfile dockerRunScript.sh docs hooks index.js lib LICENSE package.json README.md SECURITY.md src widgets yarn.lock
In the Dockerfile (Listing 1), you can see on the first line that node
[6] indicates a JavaScript theme again. In line 6, apk
is the Alpine Linux package manager [7]. If you then look at the final line of the Dockerfile, you'll see it runs node
against the index.js
file that's found in the cloned GitHub repository.
Listing 1
GitHub Dockly Dockerfile
01 FROM node:8-alpine 02 03 LABEL maintainer="Liran Tal <liran.tal@gmail.com>" 04 LABEL contributor="Eitan Schichmanter <eitan.sch@gmail.com>" 05 06 RUN apk add docker && rm -rf /var/apk/cache/* 07 08 COPY . /app 09 WORKDIR /app 10 ENV NODE_ENV production 11 RUN yarn install 12 13 CMD ["node", "index.js"]
If Docker Engine is not installed on your machine, before building a local docker image you can install the Docker CE version [8], which is preferable to the package manager versions because it's usually more up-to-date. Once installed, run docker ps
(Listing 2) to make sure that Docker Engine is happy.
Listing 2
docker ps
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
As you can see, Docker is responding nicely but is not running any containers. The first command in Listing 3 builds a Dockly container image. The second command logs in to Docker Hub, so you can pull down images (even if public), in case you've missed recent changes. Note that you have to enter your password, but for security reasons (note the warning about unencrypted passwords), you can also use access tokens (see the "Docker Hub Access Tokens" box).
Listing 3
Building a Docker Container
$ docker build -t dockly . Sending build context to Docker daemon 16.52MB Step 1/9 : FROM node:8-alpine Get https://registry-1.docker.io/v2/library/node/manifests/8-alpine: unauthorized: incorrect username or password $ docker login Authenticating with existing credentials... Stored credentials invalid or expired Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username (XXXXXX): <XXXXXX> WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
Docker Hub Access Tokens
Docker Hub offers access tokens [9], akin to GitHub, for command-line operations. I'd also recommend adding multifactor authentication (MFA) to your Docker Hub account to boost security. MFA is currently in beta on Docker Hub [10].
If you do enable MFA on Docker Hub, you'll need to use access tokens on the command line, and your password will no longer work as before. Be warned, when it comes to security on your account, the access tokens are as powerful and therefore as precious as a password. Just rerun the docker login
command and enter your Access Token in place of the password.
After logging in, you can now get the node
container image mentioned on the first line of Listing 1. From inside the Git repository in the dockly/
directory, Docker Hub should permit the downloads (Listing 4).
Listing 4
Dockly Container (abridged)
$ docker build -t dockly . Sending build context to Docker daemon 16.52MB Step 1/9 : FROM node:8-alpine 8-alpine: Pulling from library/node e6b0cf9c0882: Pull complete 93f9cf0467ca: Pull complete a564402f98da: Pull complete b68680f1d28f: Pull complete Digest: sha256:38f7bf07ffd72ac612ec8c829cb20ad416518dbb679768d7733c93175453f4d4 Status: Downloaded newer image for node:8-alpine ---> 2b8fcdc6230a [...snip...] [1/5] Validating package.json... [2/5] Resolving packages... [3/5] Fetching packages... [4/5] Linking dependencies... warning "blessed-contrib > marked-terminal@1.7.0" has incorrect peer dependency "marked@^0.3.3". [5/5] Building fresh packages... Done in 12.14s. Removing intermediate container b538567103be ---> 73affe941982 Step 9/9 : CMD ["node", "index.js"] ---> Running in 82ec51c50e49 Removing intermediate container 82ec51c50e49 ---> 04b72f9f790c Successfully built 04b72f9f790c Successfully tagged dockly:latest
Before proceeding, check for any new container images on your system. Listing 5 shows that the dockly and node images now exist. With this good news, you're now ready to run Dockly as a Docker container (Figure 1):
$ docker run -it --rm --name dockly -v /var/run/docker.sock:/var/run/docker.sock dockly
Listing 5
Local Containers
REPOSITORY TAG IMAGE ID CREATED SIZE dockly latest 04b72f9f790c About a minute ago 534MB node 8-alpine 2b8fcdc6230a 3 months ago 73.5MB
The right side of Figure 1 shows CPU and Memory information along with the number of running, paused, and stopped containers on the system. The blue bar highlights a running container, noting the container ID, the name (/dockly
, in this case), the image from which it was created (dockly
), and the entry point [11] used in the container (i.e., the main
command run by the container as it starts).
Before looking at some of the options, make sure Dockly can pick up other containers, too. In a second terminal, log in as the root user and start up the Nginx webserver:
$ docker run --name test-nginx -p80:80 -v /root/html:/usr/share/nginx/html:ro -d nginx
Mainly out of habit, I first make sure Nginx is working correctly by adding a super-simple index.html
file in the /root/html
directory. When I run the curl
command or go to http://localhost
in my browser, I can see the content of that file:
$ curl http://localhost <HTML> Hello </HTML>
Next, I'll create a database container with a command from the MySQL docs [12] and check that the database container is running in Docker Engine, as well:
$ docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=nothingtoseehere-d mysql $ docker ps | grep mysql 48f5b3719cd0 mysql "docker-entrypoint.s..." 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp test-mysql
The output shows that networking is running on TCP port 3306.
Sincerely
The Dockly terminal (Figure 1) won't refresh and pick up the Nginx and MySQL containers until you hit the Space key to force a refresh. Now you can use the cursor Up/Down keys to move between the containers that are in view.
If I select the nginx container and hit the Enter key (optionally followed by the hyphen (- ) key to expand the display further), I can see any logging output from that container. This method is very quick and clear, and the output would be a lifesaver on a system that has a heap of containers running.
Figure 2 shows the unexpanded logging output for the nginx
container. The last line of the output at the bottom records the curl
command used earlier in accessing the index.html
file. The green bar at the bottom shows other options available with shortcut keys.
For example, you can search for a container by name with the slash (/
) key, stop (s
) and restart (r
) containers, and get more information (i
) about a container (Figure 3). Notice that pressing i
for the nginx
container displays information for /root/html
, the directory with the custom HTML on the local machine.
Calling up the menu (m ) offers a number of handy options (Figure 4), some of which are a little destructive, so use them with care! The help menu (h ) summarizes the shortcut keys (Figure 5).
Buy this article as PDF
(incl. VAT)