Ever needed to make a change to all of your Docker images? It doesn't have to be a hassle!
What are base images?
Instead of basing all your Docker images from a public image, for example:
FROM alpine, make your own image to build your other images from. This allows you to easily make changes to every image that builds off your base image with one change rather than lots of identical changes in different projects.
What does that look like?
We can install software that we know all our apps need and also make config changes that all apps will need:
FROM alpine # Add labels LABEL maintainer="email@example.com" LABEL owner="company name" # Add common tools RUN apk add curl htop # Add application user RUN adduser myuser # Change from root to lower privileged user USER myuser ...
In the above example, we start from Alpine, install tools we want all our containers to have, and add a user with less privileges so that our apps don't run as root. Now lets start using our base image.
Using a base image
To start with we'll build it and tag it as
docker build . -t ourbaseimage:latest
Then we can take a look at our Dockerfile and migrate it to our new base image:
FROM alpine # Add labels LABEL maintainer="firstname.lastname@example.org" LABEL owner="company name" # Install software RUN apk add curl htop nodejs npm # Add application user RUN adduser myuser # Change from root to lower privileged user USER myuser # Copy App COPY ./app /opt/app CMD node app
We can take out everything we've already done in our base image and slim this Dockerfile down:
FROM ourbaseimage:latest # Become root to install software USER root RUN apk add nodejs npm # Change back to safer user USER myuser # Copy app COPY ./app /opt/app CMD ./app
Now we no longer have to create users, install common software or add labels in every image we build as its already done in our base image!
What are the other benefits?
Well that's easy, Security! Lets say we need to make a security fix to all our apps, that could take a long time! Not anymore, we can make our fixes in one place and it will automatically propagate out to all our Docker images.
What else? Enforcing standards. When using Docker is easy to end up with an architecture where your web server is running something like alpine but your backend services are using a completely different OS! This can get very difficult to support when developers familiar with one OS need to support a different one.
You can save yourself a lot of effort by making a Docker base image, enhance security and decrease work for developers.
Any feedback? Hit me up on our Slack! Or email me at email@example.com