DockerSlim probes and includes

As highlighted in the CNCF Software Supply Chain Best Practices, tools like DockerSlim can be used to limit the number of files in a container image, thus limiting the attack surface in the process. But what if some files your app requires were removed? :thinking:

One way to avoid that outcome is to invoke integration tests while DockerSlim is observing a container during minification. Even then, it is possible some static assets are not accessed. I had this happen recently with a static site where an image carousel hadn’t rotated through all the images, therefore some images were missing from the slim container DockerSlim created. In this article, I’ll highlight how to use DockerSlim’s probe and include features.

These are useful features that help ensure:

  • Your app is sufficiently exercised during the minification process,
  • Required directories/files are always included in slimmed containers.

:bulb: Understanding these features is also applicable to using minification in the Slim.AI Saas Developer Platform.

Probes :mag_right:

By default docker-slim will issue a GET / request with http and then https on every exposed port and then attempt to crawl any URIs it discovers. Your app may require more comprehensive probing to fully stimulate the app while it is observed by docker-slim to ensure all runtime requirements are included in the slim container image.

docker-slim has http probe commands to help facilitate that. Here’s just a couple of examples:

–http-probe-cmd

The --http-probe-cmd option is good when you want to specify a small number of simple commands. We can add --http-probe-cmd /hello to docker-slim build to add the additional GET /hello to the probe like this:

docker-slim build --http-probe-cmd /hello --tag slim-demo:prod-slim slim-demo:prod-fat

–http-probe-cmd-file

The --http-probe-cmd-file option is good when you have a lot of commands and/or you want to select additional http command options:

Here’s a probe.json for my simple app with two endpoints, / and /hello.

{
  "commands": [
  {
    "protocol": "http",
    "method": "GET",
    "resource": "/"
  },
  {
    "protocol": "http",
    "method": "GET",
    "resource": "/hello"
  }
  ]
}

Which would be invoked like this:

docker-slim build --http-probe-cmd-file probe.json --tag slim-demo:prod-slim slim-demo:prod-fat

–http-probe-exec

You can use the --http-probe-exec option to run user-provided commands when the http probes are executed. This example shows how you can run curl against the temporary docker-slim created container when the http probes are executed.

docker-slim build --http-probe-exec 'curl http://localhost:8008/hello' --publish-port 8008 --tag slim-demo:prod-slim slim-demo:prod-fat

The --http-probe-exec-file option can be used to provide a file of commands to run that stimulate the container when the http probes run.

Includes :heavy_plus_sign:

The include options are useful if you want to customize your minified image to always include specified files and directories.

–include-path

Include a directory or file. This option can be used multiple times.

Here’s an example from a static site where I always wanted some image assets included in slimmed containers.

docker-slim build --include-path /images/static --publish-port 8008 --tag slim-demo:prod-slim slim-demo:prod-fat

–include-path-file

Load directory or file includes from a file.

The --include-path-file option allows you to load multiple includes from a newline delimited file. Use this option if you have a lot of includes. The includes from --include-path and --include-path-file are combined together.

Here’s an example we used for an R app:

r_includes

/usr/local/lib/R/library/graphics
/usr/local/lib/R/library/man
/usr/local/lib/R/library/compiler
/usr/local/lib/R/library/methods
/usr/local/lib/R/library/stats
/usr/local/lib/R/library/datasets
/usr/local/lib/R/library/grDevices
/usr/local/lib/R/library/utils
/usr/local/lib/R/library/compiler
/usr/local/lib/R/library/tools
/usr/local/lib/R/site-library
/usr/local/lib/R/modules

And here is how we invoked docker-slim.

docker-slim build --include-path-file 'r_includes' --publish-port 8008 --tag slim-demo:prod-slim slim-demo:prod-fat

Summary

DockerSlim provides a good collection of options to tune how your container images are slimmed, I’ve covered just a few here. Which DockerSlim options do you find yourself using most frequently? Let us know which are most useful for the languages and frameworks you work with below :writing_hand: