What Software engineers should know about building docker files

So sounds like you want a shortcut answer, we do not have any of those in stock.

Things to note, when I talk about docker I am referring to containers in general. I know that in the world of software engineering, we are all trying to learn. I know that some of these concepts are difficult to fully remember so, refer back to this blog post next you are building a new container.

I am not providing an example of a secure image as this post is less about here copy paste this example and more about giving you the building blocks to fish for yourself.

I will make some assumptions that you have a basic understanding of what containers are and have probably built a few containers.

Part 1 - back to the basics

The best way I have seen engineers really understand docker is when they fully understand the file system they are using.

I have seen lots of engineers not understand the basics of common Linux distro’s or what the default admin user is in windows (Administrator).

If you do not have the proper foundation you will just wind up guessing and that is a high likelihood of making things worse for yourself.

Common Linux base images

  • Debian Linux
  • Alpine Linux
  • Ubuntu Linux

Part 2 - Running containers and docker context

  • Docker from some image on the internet or (internal)
  • pull and push from a registry
    • pull and run locally
    • push from local
    • push from the build pipeline
  • looking around inside the container

The big problem I see is that most engineers struggle to understand what context they are in for example knowing what the current folder path is when copy files from the local computer into the image.

part 3 - the tools and common pitfalls

Let’s talk about the tools, this list is from my experience as a full time DevSecOps engineer these are tools I use help teams daily fix their images.

  • Dive A tool for exploring a docker image, layer contents, and discovering ways to shrink the size of your Docker/OCI image.
  • Scanning tools remember to scan as you go along, and at every commit. This is why git commit hooks) are really helpful for this to become second nature.

Common pitfalls

Below is a list of common problems I have seen over my time as an information security practitioner, it is by no means exhaustive and the nature of security is subject to change which is part of the beauty of the role.

  1. STOP it!! Running your container as root – I mean come on I said the least privilege…please
  • This includes administrator for windows based containers, as I stated previously in the basics section you should take the time to have a solid foundation in how these operating systems are structured.
  1. Just because you need it in dev does not mean you need it in production. Tools like Curl should be removed, the concept is to lower attack surface area.
  2. Using more secure base images that have fewer tools or packages installed on them. One great example of this is Alpine-based images. I wanted to mention this as a side note, I personally run the latest version of a base image tag such as the following.

this is the image I use as my release layer but I think you should do the same for the build layer as well.

FROM golang:alpine

This does again require that you take the time to understand how these more locked-down operating systems work. This also means you need to take the time to understand your language and framework at a deeper level.

  1. Outdated packages, you may be bringing in more than you know.
    • On this related note, you may have outdated packages pre-installed `Think about packages like OpenSSL you are responsible to update this package.
      • These are Operating system-level packages that also need to be maintained and updated. I see a lot of cases this will be handled by updating the FROM BaseImageVersionTag that is used in the base layer of the image.
  2. Stop taking the default copy-paste container images from some website or tutorial.
    • This includes those from your editor i.e Visual Studio or Jet Brains these are meant to give you a starter template to get up and running but are not production ready.
  3. Secure or confidential information being copied over the container
    • The example here is ssh keys or certificates, Trivy scanner will highlight this for you.
  4. Dependency hell of nested packages - In some cases where packages are required of other packages these are the culprits. Meaning that you may have to locate the outdated version and update it to a secure version of it because the maintainers have not been to update the upstream package that you actually are required to run the application. In the world of C#, this takes on the deps.json located in the bin/{either debug or release} folder or in the Javascript world node modules bringing in some required package that has an open CVE. I bring these files up as the simple fix generally is to find the dependency and override the outdated vulnerable version.

Please just stop doing this

  1. Stop building images for each environment, the goal should be to build and ship one artifact. If you do not follow this pattern you end up defeating one of the main benefits of containers build and ship once. Your configuration or secrets should come from an external vault or configuration service. But hacker1db my config is not a secret why can't I just check it into my source control and ship it that way? Well if it’s good enough for your secrets and you already have to fetch them why would you not just pull all your configuration from a secure place.
  2. Don’t just fix the issue locally on your machine Open an issue on the repo of the package that has an issue give back to the community!
    1. Fix the issue if you can find some spare time to give back to those whose code you are using.
    2. Check to see if there is an open issue already on the repo, or in this case see if there is a security advisory

Tools you will benefit from

For the purposes of tools, I am going to talk about a tool that is open-source and can be used in both personal and professional projects.

NOTE: I may at some point write a blog post that talks about commercial tools and my personal thoughts on them.

Dive is super helpful for looking in the built image container when you want to see how the file system is getting evaluated.

I put this in here so that you would be able to understand how to run locally so that when you go run them in a pipeline you know what each parameter does.

I do this all time with commands I run together, if you set up your repository where the docker file is always in the same place this will be even easier. The awesome benefit of the alias is you can chain commands together for example you can do the following when building on mac.

alias dbs="docker build --tag localimage:testtag . | trivy image localimage:testtag"

Trivy is an open-source scanner you can use for free and I used it above.

Trivy Scanner example

I put Synk in here as it is built into docker cli but this is a paid product.

Pre-commit hooks are great but start with an alias and build up the habit of scanning the container image before you push the code up to the repo.

Honorable mention tools (Advanced)


Container signing with sigstore

SBOM Tools – what is SBOM

SBOM is becoming more and more important as we need to keep track of what we are bringing along for the ride in production. The best place to start here is just to list out the technology you are using in the project’s readme file of the repository. Start with the basic list of tech and build up to using these tools.

Wrap up

Thank you for sticking to the end, I know that I did not give any just do this and all the security problems will go away. I do not think that is helpful for you as that is not the reality. Technology will continue to change and we will continue to learn and get better and what we do. If you have any questions please leave a comment or message me on Twitter.

I now have a news letter, if you want to get some insider content.