-
Build 100kB Docker Images from Scratch
📓 The Gist
You may think your 100mB Alpine images are small–but how about 100kB? Smaller images ship more quickly, and contain fewer attack vectors. Moreover, by optimizing images, you discover and isolate exactly what is needed for your app to run.
Let’s Optimize.
There are two key characteristics of scratch-based docker images:
- The Dockerfile has two build stages:
- a builder–which contains all of the build dependencies including source, libraries and tools and..
- a final image, containing the binary and any run-time dependencies (config files, certificates and dynamically linked libraries)
- The final image is
FROM scratch
– the empty docker image
With this approach, your run-time image will contain exactly what is needed for your app to run – no additional config files, daemons or libraries that could be misconfigured or exploited.
-
Using Custom Docker Images on Bitbucket Build Pipeline
Usually setting up the build dependencies is a major part of each build job. Thankfully, Atlassian’s Bitbucket Pipelines, the new CI platform that integrates into Bitbucket, supports custom docker images.
To configure the build pipeline, you create
bitbucket-pipeline.yml
. This one uses our custom image (built below) and triggers builds whenever areleases-*
tag is pushed.image: tonymet/tonym.us:latest pipelines: tags: release-*: - step: script: - make sync_down_images - make s3_upload
That first line is the magic part – you can run ANY public docker image from dockerhub (and private ones as well with further setup).
-
Creating TGZ artifacts from Docker Images to Enable Service Migrations
A common migration pattern when moving to docker includes running some systems (e.g. dev, staging or a prod canary) on your docker image while the production app is still running your traditional tgz artifacts (e.g. your node app with node_modules)
Let’s create a travis build that creates two artifacts: (1) your docker image and (2) a tgz from the docker container.
Let’s assume you have a basic dockerfile with your app.js and a package.json. The key is that the app is built into
/usr/src/app