DEV Community

Farhan
Farhan

Posted on

3 1

Layering a docker image

Introduction

I’ve been a fan of immutable infrastructure ever since I used tools like Terraform and Packer. I wouldn’t say I understood the pros of it right away, but with time spent managing deployment of services in high traffic environments, one sort of understands the importance of being able to have an infrastructure which is scalable, predictable and can be recovered automatically. Who better to explain what immutable infrastructure is than Armon Dadgar himself?

Image layering

If you go through Section 2.3 of the book container best practices, they have a good section on various types of images. This brought back few of the steps I used to use previously on maintaining and building container images.

Poor quick drawing credits: sketchpad.ioPoor quick drawing credits: sketchpad.io

Base Layer

This base layer contains the operating system, core system tools, (eg: such as vim, bash, software-properties-common, curl, vim etc) and tools necessary to install packages and make updates to the image over time. The best example of such base layers are the alpine images.

FROM alpine:3.7
RUN apk update && \
apk add --no-cache xorriso git xz curl tar iptables cpio bash && \
rm -rf /var/cache/apk/*
RUN apk add -U --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing aufs-util
RUN addgroup -g 2999 docker
view raw base-layer-dock hosted with ❤ by GitHub

Dependency layer

Dependency image layers are where you would install the platform related dependencies (eg: such as Java runtime, mysql, Go, Erlang etc)

FROM mockingbird/base-image
ENV MYSQL_MAJOR 5.6
ENV MYSQL_VERSION 5.6.44-1debian9
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN { \
echo mysql-community-server mysql-community-server/data-dir select ''; \
echo mysql-community-server mysql-community-server/root-pass password ''; \
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
&& chmod 777 /var/run/mysqld \
# comment out a few problematic configuration values
&& find /etc/mysql/ -name '*.cnf' -print0 \
| xargs -0 grep -lZE '^(bind-address|log)' \
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \
# don't reverse lookup hostnames, they are usually another container
&& echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf
FROM mockingbird/base-image
ENV LANG=C.UTF-8
RUN curl -LO https://dl.google.com/go/go1.12.2.linux-amd64.tar.gz \
&& chown root:root go1.12.2.linux-amd64.tar.gz \
&& tar -xzf go1.12.2.linux-amd64.tar.gz \
&& rm go1.12.2.linux-amd64.tar.gz \
&& mv go /usr/local
WORKDIR /usr/local/lib/jre1.8.0_131
ENV GOROOT=/usr/local/go
ENV GOPATH="/Users/farhankh/go-workspace/src"
ENV PATH=$PATH:$GOPATH/bin
view raw gistfile1.txt hosted with ❤ by GitHub

Application layer

Application layer is where the dependencies specific to the container would go (eg: Database configurations, Go application code etc)

FROM mockingbird/application-go-image
RUN git clone https://github.com/dgraph-io/badger
WORKDIR /badger
WORKDIR /badger
RUN make VERBOSE=1 && make install

One can add the application specific endpoints here or add something like dumb-init.

What this helps us do is to reuse the layers at one specific stage and to use it for multiple purposes. Images being layered in this fashion will help break down large sized images into smaller images with well defined layers. It will help in faster builds, maintenance and also for reusing them as components.

References

Please follow TechLog for more.

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay