Giter Club home page Giter Club logo

docker-lock's Introduction

About

Go Report Card Build Status

docker-lock is a cli-plugin that uses Lockfiles (think package-lock.json or Pipfile.lock) to manage image digests. It allows developers to refer to images by their tags, yet receive the same immutability guarantees as if they were referred to by their digests.

If you are unsure about the differences between tags and digests, refer to this quick summary.

Demo

Consider a project with a multi-stage build Dockerfile at its root:

FROM ubuntu AS base
# ...
FROM mperel/log:v1
# ...
FROM python:3.6
# ...

Running docker lock generate from the root queries each images' registry to produce a Lockfile, docker-lock.json.

Generate GIF

Note that the Lockfile records image digests. Running docker lock verify ensures that the image digests are the same as those on the registry for the same tags.

Now, assume that a change to mperel/log:v1 has been pushed to the registry. Running docker lock verify shows that the image digest in the Lockfile is out-of-date because it differs from the newer image's digest on the registry.

Verify GIF

While developing, it can be useful to generate a Lockfile, commit it to source control, and verify it periodically (for instance on PR merges). In this way, developers can be notified when images change, and if a bug related to a change in an image crops up, it will be easy to identify.

Finally, lets assume the Dockerfile is ready to be built and shared. Running docker lock rewrite will add digests from the Lockfile to all of the images.

Rewrite GIF

At this point, the Dockerfile will contain all of the digest information from the Lockfile, so it will always maintain the same, known behavior in the future.

Features

  • Supports Dockerfiles and docker-compose v3 files.
  • Integrates with docker as the top level command, docker lock.
  • Out of the box support for public and private repos on Dockerhub, Azure Container Registry, and others via the standard docker login command or environment variables.
  • Easily extensible to any registry compliant with Docker Registry HTTP API V2.
  • Rich CLI flags with smart defaults that make selecting Dockerfiles and docker-compose files easy.
  • Installable by placing a single executable binary into docker's cli-plugins folder.
  • Written in Go.

Install

Linux / Mac

  • Docker version >= 19.03
  • mkdir -p ~/.docker/cli-plugins
  • curl -fsSL https://github.com/michaelperel/docker-lock/releases/download/{VERSION}/docker-lock-{OS} -o ~/.docker/cli-plugins/docker-lock
  • chmod +x ~/.docker/cli-plugins/docker-lock

Windows

  • Docker version >= 19.03
  • Create the folder %USERPROFILE%\.docker\cli-plugins
  • Download docker-lock-windows.exe from the releases page.
  • Rename the file docker-lock.exe
  • Move docker-lock.exe into %USERPROFILE%\.docker\cli-plugins

Tags Vs. Digests

Images can be referenced by tag or digest. For instance, at the time of writing this README, the official most recent version of the python 3.6 image on Dockerhub could be specified by tag, as in python:3.6, or by digest of the image's contents, as in python@sha256:25a189a536ae4d7c77dd5d0929da73057b85555d6b6f8a66bfbcc1a7a7de094b.

Images referenced by tag are mutable. The python maintainers could push a new image to Dockerhub with the same 3.6 tag. Downstream applications that required the previous python:3.6 image could break.

Images referenced by digest are immutable. Despite having the same tag, a newly pushed image will have a new digest. The previous image can still be referenced by the previous digest.

When deploying to Kubernetes, digests make it easy to rollback broken deployments. If your previous, working deployment relied on myimage@sha256:2273f9a536ae4d7c77d6h49k29da73057b85555d6b6f8a66bfbcc1a7a7de094b and the broken, updated deployment relies on myimage@sha256:92038492583f9a3a4d7c77d6h49k29057b85555d6b6f8a66bfbcc1a7a7d1947f, rolling back to the working deployment would be as easy as changing the digest back to the previous digest. Alternatively, if the previous, working deployment relied on myimage:v1 and the broken, updated image relies on myimage:v1, it would be more challenging to rollback by distinguishing between the images.

Although digests solve mutability problems, manually specifying them comes with a host of problems. Namely:

  • Applications will no longer benefit from updates (security updates, performance updates, etc.).
  • Dockerfiles and docker-compose files will become stale.
  • Digests are considerably less readable than tags.
  • Keeping digests up-to-date can become unwieldly in projects with many services.
  • Specifying the correct digest is complicated. Local digests may differ from remote digests, and there are many different types of digests (manifest digests, layer digests, etc.)

docker-lock solves all of these problems by storing digests in a Lockfile, allowing developers to simply use tags since digests are recorded in the background.

Contributing

Development

  • A development container based on ubuntu:bionic has been provided, so ensure docker is installed and the docker daemon is running

If using VSCode's Remote Development Extension - Containers:

  • Open the project in VSCode
  • In the command palette (ctrl+shift+p on Windows/Linux, command+shift+p on Mac), type "Reopen in Container"
  • In the command palette type: "Go: Install/Update Tools" and select all
  • When all tools are finished installing, in the command palette type: "Developer: Reload Window"
  • SSH credentials are automatically mapped into the container
  • The docker daemon is mapped from the host into the dev container, so you can use docker and docker-compose commands from within the container as if they were run on the host

Without VSCode:

  • Build the development container: docker build -f .devcontainer/Dockerfile -t dev .
  • Mount the root directory into the container, and drop into a bash shell: docker run -it -v ${PWD}:/workspaces/docker-lock dev

CI

  • Unit tests, integration tests, and linting run in the CI pipeline on pull requests.
  • To format your code: ./tools/format.sh
  • To lint your code: ./tools/lint.sh
  • To run unit tests: ./tools/unittest.sh
  • To generate a coverage report: ./tools/coverage.sh
  • To view the coverage report on your browser, open a console, but not in docker, run go tool cover -html=coverage.out

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.