• Stars
    star
    4,033
  • Rank 10,787 (Top 0.3 %)
  • Language
    Dockerfile
  • License
    Other
  • Created about 4 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Dockerfile best-practices for writing production-worthy Docker images.

Dockerfile best practices Hexops logo

Writing production-worthy Dockerfiles is, unfortunately, not as simple as you would imagine. Most Docker images in the wild fail here, and even professionals often[1] get[2] this[3] wrong[4].

This repository has best-practices for writing Dockerfiles that I (@slimsag) have quite painfully learned over the years both from my personal projects and from my work @sourcegraph. This is all guidance, not a mandate - there may sometimes be reasons to not do what is described here, but if you don't know then this is probably what you should be doing.

How to use this

Copy the Dockerfile into your own project and follow the comments to create your Dockerfile.

Best practices included in the Dockerfile

The following are included in the Dockerfile in this repository:

Run as a non-root user

Running containers as a non-root user substantially decreases the risk that container -> host privilege escalation could occur. This is an added security benefit. (Docker docs, Bitnami blog post)

Do not use a UID below 10,000

UIDs below 10,000 are a security risk on several systems, because if someone does manage to escalate privileges outside the Docker container their Docker container UID may overlap with a more privileged system user's UID granting them additional permissions. For best security, always run your processes as a UID above 10,000.

Use a static UID and GID

Eventually someone dealing with your container will need to manipulate file permissions for files owned by your container. If your container does not have a static UID/GID, then one must extract this information from the running container before they can assign correct file permissions on the host machine. It is best that you use a single static UID/GID for all of your containers that never changes. We suggest 10000:10001 such that chown 10000:10001 files/ always works for containers following these best practices.

Do not use latest, pin your image tags

We suggest pinning image tags using a specific image version using major.minor, not major.minor.patch so as to ensure you are always:

  1. Keeping your builds working (latest means your build can arbitrarily break in the future, whereas major.minor should mean this doesn't happen)
  2. Getting the latest security updates included in new images you build.

Why you perhaps shouldn't pin with a SHA

SHA pinning gives you completely reliable and reproducable builds, but it also likely means you won't have any obvious way to pull in important security fixes from the base images you use. If you use major.minor tags, you get security fixes by accident when you build new versions of your image - at the cost of builds being less reproducable.

Consider using docker-lock: this tool keeps track of exactly which Docker image SHA you are using for builds, while having the actual image you use still be a major.minor version. This allows you to reproduce your builds as if you'd used SHA pinning, while getting important security updates when they are released as if you'd used major.minor versions.

If you're a large company/organization willing to spin up infrastructure like image security scanners, automated dependency updating, etc. then consider this approach as well.

Use tini as your ENTRYPOINT

We suggest using tini as the ENTRYPOINT in your Dockerfile, even if you think your application handles signals correctly. This can alter the stability of the host system and other containers running on it, if you get it wrong in your application. See the tini docs for details and benefits:

Using Tini has several benefits:

  • It protects you from software that accidentally creates zombie processes, which can (over time!) starve your entire system for PIDs (and make it unusable).
  • It ensures that the default signal handlers work for the software you run in your Docker image. For example, with Tini, SIGTERM properly terminates your process even if you didn't explicitly install a signal handler for it.
  • It does so completely transparently! Docker images that work without Tini will work with Tini without any changes.

Only store arguments in CMD

By having your ENTRYPOINT be your command name:

ENTRYPOINT ["/sbin/tini", "--", "myapp"]

And CMD be only arguments for your command:

CMD ["--foo", "1", "--bar=2"]

It allows people to ergonomically pass arguments to your binary without having to guess its name, e.g. they can write:

docker run yourimage --help

If CMD includes the binary name, then they must guess what your binary name is in order to pass arguments etc.

Install bind-tools if you care about DNS resolution on some older Docker versions

If you want your Dockerfile to run on old/legacy Linux systems and Docker for Mac versions and wish to avoid DNS resolution issues, install bind-tools.

For additional details see here.

(Applies to Alpine Linux base images only)

FAQ

Is tini still required in 2020? I thought Docker added it natively?

Unfortunately, although Docker did add it natively, it is optional (you have to pass --init to the docker run command). Additionally, because it is a feature of the runtime and e.g. Kubernetes will not use the Docker runtime but rather a different container runtime it is not always the default so it is best if your image provides a valid entrypoint like tini instead.

Should I really use major.minor over SHA pinning?

It depends. We advise major.minor pinning here because we believe it is the most likely thing that the average developer creating a new Docker image can effectively manage day-to-day that provides the most security. If you're a larger company/organization, you might consider instead however:

  • Using one of the many tools for automated image vulnerability scanning, such as GCR Vulnerability Scanning so you know when your images have vulnerabilities.
  • Using SHA pinning so you know your images will not change without your approval.
  • Using automated image tag update software, such as Renovate to update your image tags and get notified.
  • An extensive review process to ensure you don't accept untrustworthy image tag updates.

However, this obviously requires much more work and infrastructure so we don't advise it here with the expectation that most people would pin a SHA and likely never update it again - thus never getting security fixes into their images.

More Repositories

1

mach

zig game engine & graphics toolkit
Zig
3,065
star
2

vecty

Vecty lets you build responsive and dynamic web frontends in Go using WebAssembly, competing with modern web frameworks like React & VueJS.
Go
2,790
star
3

mach-glfw

Ziggified GLFW bindings with 100% API coverage, zero-fuss installation, cross compilation, and more.
Zig
344
star
4

valast

Convert Go values to their AST
Go
305
star
5

autogold

Automatically update your Go tests
Go
282
star
6

fastfilter

fastfilter: Binary fuse & xor filters for Zig (faster and smaller than bloom filters)
Zig
249
star
7

mach-core

window+input+GPU, truly cross-platform
Zig
184
star
8

mach-gpu

mach/gpu: truly cross-platform WebGPU graphics for Zig
Zig
182
star
9

mach-gpu-dawn

Google's Dawn WebGPU implementation, cross-compiled with Zig into a single static library
Zig
144
star
10

gotextdiff

Unified text diffing in Go (copy of the internal diffing packages the officlal Go language server uses)
Go
129
star
11

mach-sysgpu

Highly experimental, blazingly fast, lean & mean descendant of WebGPU written in Zig
Zig
95
star
12

mach-examples

Mach engine examples
Zig
86
star
13

dawn

Fork of dawn.googlesource.com/dawn with generated code and third-party dependencies committed
C++
78
star
14

zorex

Zorex: the omnipotent regex engine
Zig
66
star
15

mach-dxcompiler

DXC built using Zig
C++
53
star
16

Azure-Kinect-Python

Python 3 bindings for the Azure Kinect SDK
Python
48
star
17

mach-freetype

Ziggified Freetype 2 bindings with zero-fuss installation, cross compilation, and more.
Zig
46
star
18

zgo

Go + Zig = 💕 | Zig and Go are best friends
Go
38
star
19

mach-glfw-vulkan-example

mach-glfw Vulkan example
Zig
37
star
20

mach-glfw-opengl-example

Example for using mach-glfw with zig-opengl
Zig
35
star
21

mach-ecs

Entity Component System from first-principles designed for Zig
34
star
22

mach-sysaudio

cross-platform low-level audio IO in Zig
Zig
29
star
23

mach-sysjs

enables Zig/WASM to speak to JavaScript
Zig
28
star
24

awesome-zig-gamedev

Comprehensive collection of maintained zig gamedev projects & libraries
17
star
25

xcode-frameworks

XCode frameworks packaged for the Zig build system
C
17
star
26

mach-core-starter-project

The result of running through https://machengine.org/core/getting-started
Zig
16
star
27

mach-gamemode

mach-gamemode: make your Linux games go brrr
14
star
28

harfbuzz

A fork of harfbuzz packaged for the Zig build system
C++
13
star
29

brotli

A fork of brotli packaged for the Zig build system
C
12
star
30

cmder

Lightweight Go pattern for writing CLIs with subcommands
Go
12
star
31

pgtrgm_emperical_measurements

Emperical measurements of pg_trgm performance at scale
Shell
11
star
32

zigmonthly.org

Curated Zig news brought to you by @slimsag each month
SCSS
11
star
33

mach-system-sdk

DirectX 12 headers for MinGW/Zig, cross-compile DX12/Metal/etc with Zig, etc.
10
star
34

glfw

A fork of GLFW packaged for the Zig build system
C
10
star
35

machengine.org

machengine.org website, documentation, etc.
SCSS
10
star
36

sdk-macos-11.3

Also see https://github.com/hexops/sdk-macos-12.0
C
9
star
37

libmach

C API to Mach core and Mach engine
C
9
star
38

vulkan-zig-generated

Snektron/vulkan-zig, but generated and comitted for use as a package manager dependency
Zig
9
star
39

wrench

[bot] 🐵 Wrench here! Let's fix this! 🔧
Go
9
star
40

freetype

A fork of freetype packaged for the Zig build system
C
9
star
41

mach-editor

Mach CLI and graphical editor
Zig
8
star
42

devlog

Hexops devlog
SCSS
7
star
43

vulkan-headers

A fork of vulkan-headers packaged for the Zig build system
C++
7
star
44

x11-headers

x11-headers packaged for the Zig build system
C
7
star
45

mach-model3d

compact, featureful model format & alternative to glTF
C
7
star
46

font-assets

Various fonts packaged for the Zig build system
Zig
7
star
47

sinter

Sinter text search engine
Zig
6
star
48

mach-objc

Generated Objective-C bindings for Zig
Zig
6
star
49

basisu

A fork of basisu packaged for the Zig build system
C
6
star
50

sdk-macos-12.0

macOS 12.0 Monterey SDK for Mach engine
C
6
star
51

mach-basisu

basis universal (supercompressed textures) for Zig
Zig
6
star
52

mach-opus

Opus audio decoding and encoding for Zig via the battle-hardened xiph.org libopus
Zig
5
star
53

linux-audio-headers

linux-audio-headers packaged for the Zig build system
C
5
star
54

mach-rs

Rust bindings for Mach
5
star
55

wayland-headers

wayland-headers packaged for the Zig build system
C
5
star
56

spirv-tools

A fork of spirv-tools packaged for the Zig build system
C++
4
star
57

ControlCursor

A C# library for getting and setting global cursor position.
C#
4
star
58

direct3d-headers

Enables using the latest Direct3D headers and libraries with Zig
C
4
star
59

mach-flac

FLAC audio decoding and encoding for Zig via the battle-hardened xiph.org libflac
Zig
4
star
60

hexi-old

Hexi: Game Engine & Graphics Toolkit
Rust
4
star
61

sycl24

Software You Can Love 2024 workshop
Zig
4
star
62

spirv-cross

A fork of spirv-cross packaged for the Zig build system
C++
3
star
63

hexops.com

hexops.com website
SCSS
3
star
64

opengl-headers

opengl-headers packaged for the Zig build system
C
3
star
65

soundio

libsoundio upstream sources used by Mach engine
C
3
star
66

sdk-macos-13.3

macOS 13.3 Ventura SDK for Mach engine
C
3
star
67

sdk-linux-x86_64

Linux x86_64 SDK for Mach engine
C++
3
star
68

mach-ggml

Zig
3
star
69

lordofzero

Shell
3
star
70

opusfile

A fork of opusfile packaged for the Zig build system
C
2
star
71

sdk-linux-aarch64

Linux aarch64 SDK for Mach engine
C++
2
star
72

ogg

A fork of ogg packaged for the Zig build system
C
2
star
73

directx-headers

A fork of DirectX-Headers, packaged with the Zig build system and compatible with cross-compilation
C
2
star
74

sdk-windows-x86_64

Windows x86_64 SDK for Mach engine
C
2
star
75

mach-objc-generator

Zig Objective-C binding generator
Zig
2
star
76

mach-example-assets

mach-core examples assets
Zig
2
star
77

heapbit

1
star
78

tridex-assets

Static contents / assets for Tridex
1
star
79

opus

A fork of opus packaged for the Zig build system
C
1
star
80

opusenc

A fork of libopusenc packaged for the Zig build system
C
1
star
81

ztemplate

Hexops Zig template repository
Zig
1
star
82

flac

A fork of flac packaged for the Zig build system
C
1
star
83

stackptr

1
star