Tuesday, 23 February 2021

Munging Dockerfiles using sed

 So I had a requirement to update a Dockerfile, which I'd pulled from a GitHub repository, without actually adding my changes ( via git add and git commit ) to that repo ...

Specifically, I wanted to add a command to update the to-be-built Alpine image.

Here's how I solved it ...

Having cloned the target repo, which included the Dockerfile ( example below ): -

FROM alpine:3.7
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]

At present, this is what happens when I build the image: -

docker build -f Dockerfile .

Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine:3.7
3.7: Pulling from library/alpine
5d20c808ce19: Pull complete 
Digest: sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10
Status: Downloaded newer image for alpine:3.7
 ---> 6d1ef012b567
Step 2/3 : RUN apk add --no-cache mysql-client
 ---> Running in 07bc9ca0e14a
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/6) Installing mariadb-common (10.1.41-r0)
(2/6) Installing ncurses-terminfo-base (6.0_p20171125-r1)
(3/6) Installing ncurses-terminfo (6.0_p20171125-r1)
(4/6) Installing ncurses-libs (6.0_p20171125-r1)
(5/6) Installing mariadb-client (10.1.41-r0)
(6/6) Installing mysql-client (10.1.41-r0)
Executing busybox-1.27.2-r11.trigger
OK: 41 MiB in 19 packages
Removing intermediate container 07bc9ca0e14a
 ---> 43862371f8a4
Step 3/3 : ENTRYPOINT ["mysql"]
 ---> Running in d8b08c967cc1
Removing intermediate container d8b08c967cc1
 ---> 1ee30800ffbd
Successfully built 1ee30800ffbd

I wanted to add a command to run apk upgrade before the ENTRYPOINT entry ( so, in essence, inserting it between lines 2 and 3 )

This is what I did: -

sed -i '' -e "2s/^//p; 2s/^.*/RUN apk --no-cache upgrade/" Dockerfile

which results in: -

FROM alpine:3.7
RUN apk add --no-cache mysql-client
RUN apk --no-cache upgrade
ENTRYPOINT ["mysql"]

Now the build looks like this: -

docker build -f Dockerfile .

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM alpine:3.7
3.7: Pulling from library/alpine
5d20c808ce19: Pull complete 
Digest: sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10
Status: Downloaded newer image for alpine:3.7
 ---> 6d1ef012b567
Step 2/4 : RUN apk add --no-cache mysql-client
 ---> Running in b29668e70377
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/6) Installing mariadb-common (10.1.41-r0)
(2/6) Installing ncurses-terminfo-base (6.0_p20171125-r1)
(3/6) Installing ncurses-terminfo (6.0_p20171125-r1)
(4/6) Installing ncurses-libs (6.0_p20171125-r1)
(5/6) Installing mariadb-client (10.1.41-r0)
(6/6) Installing mysql-client (10.1.41-r0)
Executing busybox-1.27.2-r11.trigger
OK: 41 MiB in 19 packages
Removing intermediate container b29668e70377
 ---> 971a3d538edf
Step 3/4 : RUN apk --no-cache upgrade
 ---> Running in 8dfa10b481ad
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/2) Upgrading musl (1.1.18-r3 -> 1.1.18-r4)
(2/2) Upgrading musl-utils (1.1.18-r3 -> 1.1.18-r4)
Executing busybox-1.27.2-r11.trigger
OK: 41 MiB in 19 packages
Removing intermediate container 8dfa10b481ad
 ---> 35d7cbec77c0
Step 4/4 : ENTRYPOINT ["mysql"]
 ---> Running in c0d7d310d396
Removing intermediate container c0d7d310d396
 ---> 4ad02b88f4d4
Successfully built 4ad02b88f4d4

In essence, the sed command duplicates line 2: -

RUN apk add --no-cache mysql-client

as line 3, and then replaces the newly duplicated text with the required replacement: -

RUN apk --no-cache upgrade

Neat, eh ?

I've got this in a script, and it works a treat .....

No comments:

Yay, VMware Fusion and macOS Big Sur - no longer "NAT good friends" - forgive the double negative and the terrible pun ...

After macOS 11 Big Sur was released in 2020, VMware updated their Fusion product to v12 and, sadly, managed to break Network Address Trans...