Docker and sed
I saw my teammate use the Terminal tab of Docker Desktop. I initially tried with running ubuntu:latest
and alpine:latest
. Eventually, I remembered that he used redis:latest
as the container image. So why does the container using redis continue running, but the ubuntu does not?
The idea is that a docker container will exit running if there is no more processes left to run. It turns out that redis is “commonly used as an in-memory data store or cache, and it’s designed to run continuously to serve incoming requests. Therefore, the Redis container doesn’t exit immediately because the Redis process remains active.”
I am using sed
to make changes to a configuration file when the docker image is built. The app will display the build time, and I am setting that in the Dockerfile.
First, let’s go over what sed is and its syntax. sed
stands for "stream editor" and is a powerful command-line utility for text manipulation in Unix-like operating systems. It is commonly used for tasks such as searching, replacing, inserting, and deleting text in files or streams of data.
Personally, I use it for replacing a string of text in files.
The basic syntax of sed is as follows:
sed options 'command' file
Here’s a breakdown of each component:
options
: These are optional flags that modify the behavior ofsed
. Some commonly used options include:
-i
: Modifies the file in-place (i.e., changes are made directly to the file).
-e
: Allows specifying multiple commands.
'command'
: This represents the actual editing command(s) to be executed. Several commands can be combined, separated by semicolons (;) or using the-e
option.
Commands can operate on a range of lines, specified using line numbers or patterns.
Common commands include:
s/pattern/replacement/
: Substitutes the first occurrence ofpattern
withreplacement
on each line.s/pattern/replacement/g
: Substitutes all occurrences ofpattern
withreplacement
on each line./pattern/command
: Executescommand
if the line matchespattern
.d
: Deletes the current line.p
: Prints the current line.
file
: Specifies the name of the file(s) to be processed. If omitted,sed
reads from standard input.
So to replace a placeholder like <BUILD_TIME>
with the date in the version.json
at time of image build, I would type: RUN sed -i "s/<BUILD_TIME>/$(date)/g" version.json
.
The -i
makes the replacement inside the version.json
instead of stdout. The $()
takes the result of the command inside the parentheses and performs string interpolation, expanding it to:
"s/<BUILD_TIME>/Mon May 15 22:11:01 PDT 2023/g" version.json
date
is a CLI utility. It can be customized, for example $(date +%d-%b-%Y)
will display 15-May-2023
.
For more information on the date
utility:
The basic syntax of the date
command is as follows:
date [options] [+FORMAT]
Here’s a breakdown of each component:
options
: These are optional flags that modify the behavior of thedate
command. Some commonly used options include:
-u
or --utc
: Display or set the date in Coordinated Universal Time (UTC).
-d
or --date
: Specify a specific date and time rather than the current system
+FORMAT
: This specifies the output format of the date and time. The+
character is used to indicate that a format string follows. There are various format specifiers that can be used to represent different components of the date and time, such as%Y
for the year,%m
for the month,%d
for the day,%H
for the hour,%M
for the minute,%S
for the second, and more.
Ex: Display the current date and time in a specific format (e.g., “YYYY-MM-DD HH:MM:SS”):
date +"%Y-%m-%d %H:%M:%S"
PS: One lesson, when the Docker image is being built it may not have access to the K8s secrets in the production environment. So if I try to run RUN sed -i "s/<VERSION>/${APPLICATION_VERSION}/g" version.json
, it would not necessarily have access to the APPLICATION_VERSION
environment variable K8s secret.