Giter VIP home page Giter VIP logo

r10edocker's Introduction

r10edocker: Reproducible Docker Container for Go Applications

sanity checks

r10edocker creates a framework for making bit-for-bit reproducible Docker container images for Go applications. If you deploy backend services as containers, and care about software supply chain security, reproducible Docker containers are for you.

If your Go application is locally reproducible (i.e., it's reproducible on your local build machine), the containing Docker container is universally reproducible (i.e., it's reproducible on different build machines).

There are some pleasant side-effects

  • As a corollary of reproducible container, the executables in it are reproducible. It means that even if you don't care about containerization, r10edocker provides a means to get you (universally) reproducible Go applications. We provide a utility container_cp.sh to extract a file from a container image, in case it helps you.
  • The resulting Docker container is minimum, in that it contains only the application(s), but does not include an OS shell, a package manager, etc. Minimum containers minimize attack surface.

FAQs

What are the constraints

Currently, r10edocker only

  • works for "pure" Go projects, i.e., those that do not use cgo
  • produces x86_64 Docker images

What if my Go application is not locally reproducible

In general, Go makes it easy to get reproducible statically linked executables. If your Go application is not reproducible, make sure you

  • use go.sum files
  • use the -trimpath flag when go build
  • don't insert any timestamp information in the executable
  • and as a last resort, perform debugging to find out what causes the builds to be non-deterministic using these recommended tools

How to Use

install r10edocker

# commit SHA for v0.3.2. Pin commit because it's less malleable than a tag
go install github.com/syncom/r10edocker@6bd8d3c61071f82b4c46bb76a05fd1230a2bee13

Set up your Go project for reproducible Docker builds

Configure your Go project in a JSON file

Create a simple configuration file, config.json, and put it in your project directory. You will also want to check this file in your project's repository for version control.

Here's an example: config.json

{
  "project_name": "go-r10e-docker",
  "build_cmd": "scripts/build-all.sh",
  "maintainers": [ "syncom" ],
  "artifacts": [
    {
      "src": "build/r10edocker-linux-amd64",
      "dest": "/app/r10edocker-linux-amd64"
    },
    {
      "src": "build/r10edocker-linux-arm64",
      "dest": "/app/r10edocker-linux-arm64"
    },
    {
      "src": "build/r10edocker-darwin-amd64",
      "dest": "/app/r10edocker-darwin-amd64"
    },
    {
      "src": "build/r10edocker-darwin-arm64",
      "dest": "/app/r10edocker-darwin-arm64"
    }
  ],
  "extern_data": [
    {
      "src": "LICENSE",
      "dest": "/LICENSE"
    }
  ]
}

Fields "project_name", "build_cmd", and "artifacts" are mandatory. Fields "maintainers" and "extern_data" are optional.

Name Value Type Can be null or empty
project_name string false
build_cmd string false
maintainers array of strings true
artifacts array of objects false
extern_data array of objects true
  • "project_name" is a name to identify your project. Your reproducible container image will be named after it. Please make sure there's no whitespace characters in the "project_name" value
  • "build_cmd" is a one-line command to build your Go application(s). You may use a shell script file for it
  • "artifacts" contains information about the source and destination path information for the Go executable(s) to get into the container image
    • "src" shall be a relative path of the executable file (built with "build_cmd" on a build host) with respect to the project's directory root
    • "dest" shall be an absolute path of the executable file in the final Docker container image
  • "maintainer" contains a list of project maintainer names/aliases/GitHub handles
  • "extern_data" contains information about the source and destination path information for data external to the Go executable(s) to get into the container. Unlike in "artifacts", the external data path can be either a file or a directory. However, the source and destination paths for the same external datum must be of the same type (file or directory) when instantiated.

Generate r10e build scripts, and build

Make sure you have the Docker daemon running and sha256sum (provided by coreutils) in your PATH. Under your Go project's directory root, run

$ r10edocker -c config.json
2022/10/15 20:08:33 R10e build scripts created in 'r10e-docker'

The build scripts are created in subdirectory r10e-docker using information in config.json. You should also check in the r10e-dockerdirectory to your source repository.

Now our reproducible Docker container can be built with command (with sample output)

$ bash r10e-docker/build_container.sh 2>/dev/null
[...]
======= CONTAINER IMAGE INFO ========
Container image created in /home/syncom/Development/r10edocker/r10e-docker/out/go-r10e-docker-latest.tar.gz
IMAGE sha256sum: 43052c5df509e35e5b0fb8c107a63e72025aa9fc75b3596961241b965c8168d4
IMAGE ID: 05026ca1fc5df69f54ece62ec8fd8eba8b37f7628a00ee872ab802b74a820b88

The reproducible container is named <project_name>.tar.gz, and can be loaded with

docker load -i r10e-docker/out/<project_name>-latest.tar.gz

Update r10e build scripts

If you need to change your Go project or Docker container's configuration, modify your config.json, and repeat all the steps described in the previous section to get the content of r10e-docker/ updated.

Acknowledgments

  • Dino Dai Zovi (@ddz): for suggesting Nix to me, and for his encouragement
  • My colleagues at Thistle and Cash App: for their feedback on earlier versions of this work, and for independently reproducing and verifying the build steps

r10edocker's People

Contributors

nmahendru avatar syncom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

nmahendru

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.