If you love Docker then you might be sharing one of the biggest pains when it comes to running your builds from the console. The output by default lacks coloring and its hard to tell whats going on by looking at a lot of repetitive text.

I’ve dedicated a few hours to enhancing the docker image build console output by adding color to various text fragments, and the result is fantastic. I am really excited to share it with you.

First things first, I whipped up a multi-stage Dockerfile for a fun little NodeJS project. I used NCC to bundle my whole NodeJS app and its modules into one slick .JS file, making my final Docker image way smaller. With NCC, I shrank it from a whopping 1GB to just 133.99MB!

Here is the file and a gist link, I’ve explained every bit of it in the code itself but here is a line by line explanation of it.
https://gist.github.com/jsmuster/70082c79d95d663a872d14a67166ff11

Stage 1: Builder

This is the part which creates a temporary Docker image used to compile our NodeJS application code into one single Javascript file, which is used in the next step of our multi-stage build.

Base Image

FROM node:lts-alpine as builderUses the latest long-term support (LTS) version of Node.js with an Alpine Linux base image for the builder stage. Alpine is chosen for its small size and efficiency.

Environment Variable

ENV NODE_ENV=productionSets the NODE_ENV environment variable to production, indicating that the application is in production mode.

Working Directory

WORKDIR /usr/src/appSets the working directory inside the container to /usr/src/app

Copy Package Files

COPY [“package.json”, “package-lock.json*”, “npm-shrinkwrap.json*”, “./”]Copies package.json, package-lock.json, and npm-shrinkwrap.json (if they exist) to the working directory. These files are used to install the necessary dependencies.

Install Dependencies

RUN npm install –productionInstalls the production dependencies listed in the prior step.

Install NCC

RUN npm install -g @zeit/nccGlobally installs ncc (Node.js Compiler Collection), used to compile the Node.js project into a single file.

Copy Source Code

COPY . .Copies the rest of the application source code to the working directory.

Build Project

RUN export NODE_OPTIONS=–openssl-legacy-provider && ncc build ./bin/www -o distSets NODE_OPTIONS to use the OpenSSL legacy provider and runs ncc to compile the project located at ./bin/www into a single file output in the dist directory.

Remove Node Modules

RUN rm -rf node_modulesRemoves the node_modules directory to save space since it is no longer needed after the project is build.

Expose Port

EXPOSE 3000Informs Docker that the container listens on port 3000.

Stage 2: Build the actual Docker image

This is the part that builds the actual image

Base Image

FROM node:lts-alpine as backendUses the same Node.js LTS Alpine image for our NodeJS application.

Environment Variable

ENV NODE_ENV=productionSets the NODE_ENV environment variable to production.

Working Directory

WORKDIR /usr/src/appSets the working directory inside the container to /usr/src/app. You could change this to anything you like.

Copy Compiled Files

COPY –from=builder /usr/src/app/dist .Copies the compiled files from the dist directory of the builder docker image to the working directory of the current docker image.

Define Command

CMD [“node”, “index.js”]Sets the default command to run the application using node index.js.

Now here is the actual script I wrote to enhance the Docker build output.

Because trying to read a detailed Docker build log without any color is like watching a mime perform in the dark — you know something is happening, but you have no idea what.

The process began with an attempt to color the initial dash and number pattern “#1”. Once this step was successful, I was able to proceed and convert the entire output accordingly. Here is a small snippet of the output:

I’ve shared the script on Github gists, so go ahead and use it as boiler plate and enhance it even further. Lets break this code down line by line:

https://gist.github.com/jsmuster/fcce009ddb35fa15f2f409b20c4c94f2

Shebang

#!/bin/shThis specifies that the script should be run using the sh shell. This is a part of every shell script by default, just make sure to have this at the top of the file, otherwise your scripts won’t execute.

ANSI Color Codes

# Regular text colors
BLACK=’33[0;30m’
RED=’33[0;31m’
GREEN=’33[0;32m’
YELLOW=’33[0;33m’
BLUE=’33[0;34m’
MAGENTA=’33[0;35m’
CYAN=’33[0;36m’
WHITE=’33[0;37m’

# Bold text colors
BOLD_BLACK=’33[1;30m’
BOLD_RED=’33[1;31m’
BOLD_GREEN=’33[1;32m’
BOLD_YELLOW=’33[1;33m’
BOLD_BLUE=’33[1;34m’
BOLD_MAGENTA=’33[1;35m’
BOLD_CYAN=’33[1;36m’
BOLD_WHITE=’33[1;37m’

# Background colors
BG_BLACK=’33[40m’
BG_RED=’33[41m’
BG_GREEN=’33[42m’
BG_YELLOW=’33[43m’
BG_BLUE=’33[44m’
BG_MAGENTA=’33[45m’
BG_CYAN=’33[46m’
BG_WHITE=’33[47m’

NC=’33[0m’ # No ColorDefines various ANSI color codes for regular text, bold text, and background colors. We’re going to use these to color output in the console.

Colored Echo Functions

echo_red() {
echo “${RED}$1${NC}”
}

echo_green() {
echo “${GREEN}$1${NC}”
}

echo_yellow() {
echo “${YELLOW}$1${NC}”
}

echo_blue() {
echo “${BLUE}$1${NC}”
}Defines functions to print text in specific colors (red, green, yellow, and blue).

Colorize Output Function

colorize_output() {
while IFS= read -r line; do
# Check for the pattern “#[0-9]* CACHED” and colorize it
if echo “$line” | grep -q “#[0-9]*”; then
# Apply color to the matched pattern
line=$(color_pattern “$line”)
fi
echo “$line”
done
}Reads lines from the input and checks for patterns to colorize using the color_pattern function. The IFS= read -r line loop reads lines without trimming whitespace.

Color Pattern Function

color_pattern() {

local input=”$1″
local red=’\033[0;31m’

local green=’\033[0;32m’
local yellow=’\033[0;33m’
local blue=’\033[0;34m’

local black=’\033[0;30m’
local magenta=’\033[0;35m’
local cyan=’\033[0;36m’
local white=’\033[0;37m’

# Bold text colors
local bold_black=’\033[1;30m’
local bold_red=’\033[1;31m’
local bold_green=’\033[1;32m’
local bold_yellow=’\033[1;33m’
local bold_blue=’\033[1;34m’
local bold_magenta=’\033[1;35m’
local bold_cyan=’\033[1;36m’
local bold_white=’\033[1;37m’

# Background colors
local bg_black=’\033[40m’
local bg_red=’\033[41m’
local bg_green=’\033[42m’
local bg_yellow=’\033[43m’
local bg_blue=’\033[44m’
local bg_magenta=’\033[45m’
local bg_cyan=’\033[46m’
local bg_white=’\033[47m’

local reset=’\033[0m’
local pattern=”#[0-9]+”

input=$(echo “$input” | sed -E “s/($pattern)/${bold_white}${bg_black}1${reset}/g”)

pattern=”DONE”

input=$(echo “$input” | sed -E “s/($pattern)/${green}1${reset}/g”)

pattern=”exporting”

input=$(echo “$input” | sed -E “s/($pattern)/${green}1${reset}/g”)

pattern=”writing image”

input=$(echo “$input” | sed -E “s/($pattern)/${bold_black}1${reset}/g”)

pattern=”[0-9]+.[0-9]+s”

input=$(echo “$input” | sed -E “s/($pattern)/${blue}1${reset}/g”)

pattern=”CACHED”

input=$(echo “$input” | sed -E “s/($pattern)/${yellow}1${reset}/g”)

pattern=”[internal]”

input=$(echo “$input” | sed -E “s/($pattern)/${cyan}1${reset}/g”)

pattern='[builder [0-9]+/[0-9]+]’

input=$(echo “$input” | sed -E “s/([builder [0-9]+/[0-9]+])/${bold_green}1${reset}/g”)

pattern='[backend [0-9]+/[0-9]+]’

input=$(echo “$input” | sed -E “s/([backend [0-9]+/[0-9]+])/${magenta}1${reset}/g”)

# Return the modified string
echo “$input”
}This function holds local color variables because it needs to escape the strings, it applies various color codes to different patterns in the input string using sed. SED is a stream editor in Linux.

Initial Status Message

echo_green “Starting the build script…”Prints a message indicating the start of the build script in green.

Run Docker Build Function

run_docker_build() {
docker image build –progress=plain -t cybernetically-web-backend:latest . 2>&1 | tee dockerbuild.log | colorize_output
}Defines a function to run the Docker build command and pipe its output to both a log file and the colorize_output function. This is the line that runs the docker build, you want to replace the “cybernetically-web-backend:latest” name of the image to something of your own. This will also output your build log into dockerbuild.log

Execute Docker Build

run_docker_buildCalls the run_docker_build function to start the Docker build process with colorized output.

Final Status Message

echo_green “build script finished.”Prints a message indicating the completion of the build script in green.

Weekend Docker Build Makeover: Tips and Tricks was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.

​ Level Up Coding – Medium

about Infinite Loop Digital

We support businesses by identifying requirements and helping clients integrate AI seamlessly into their operations.

Gartner
Gartner Digital Workplace Summit Generative Al

GenAI sessions:

  • 4 Use Cases for Generative AI and ChatGPT in the Digital Workplace
  • How the Power of Generative AI Will Transform Knowledge Management
  • The Perils and Promises of Microsoft 365 Copilot
  • How to Be the Generative AI Champion Your CIO and Organization Need
  • How to Shift Organizational Culture Today to Embrace Generative AI Tomorrow
  • Mitigate the Risks of Generative AI by Enhancing Your Information Governance
  • Cultivate Essential Skills for Collaborating With Artificial Intelligence
  • Ask the Expert: Microsoft 365 Copilot
  • Generative AI Across Digital Workplace Markets
10 – 11 June 2024

London, U.K.