Skip to content

Instantly share code, notes, and snippets.

@mlocher
Forked from krtierney/Dockerfile
Last active September 21, 2017 12:39
Show Gist options
  • Save mlocher/a5a84dd5577cd69921d42d4fa3777005 to your computer and use it in GitHub Desktop.
Save mlocher/a5a84dd5577cd69921d42d4fa3777005 to your computer and use it in GitHub Desktop.
Dockerfile best practices
FROM ruby:2.3.0
LABEL maintainer="Kaitlyn Tierney, kaitlyn@happybearsoftware.com"
ENV RAILS_ENV=test
RUN apt-get update -qq \
&& apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
postgresql-common \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir -p /app
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN gem install bundler \
&& bundle install -j20 --without development production
COPY . ./
@mlocher
Copy link
Author

mlocher commented Sep 21, 2017

A couple comments :)

There are multiple Dockerfile linters available, e.g. http://hadolint.lukasmartinelli.ch or https://www.fromlatest.io (I personally prefer fromlatest.io right now). They are a great way to keep up with best practices and make sure your Dockerfiles follow them.

I made the following changes to the original Dockerfile

  1. Added a maintainer LABEL on line 2, to make it easy to figure out who's maintaining the image. This is not strictly required, but useful, especial for public images.

  2. Move the ENV directive to the topic, as it's unlikely to change and this way the cache can be used in most cases.

  3. Add --no-install-recommends to the package installation commands, to keep the size of the Docker image down, additionally clean the apt cache at the end of the RUN command via rm -rf /var/lib/apt/lists/*

  4. Have each package on its own line and sort them alphabetically. (This reduces the chance of installing packages twice and makes it easier to see which packages are getting installed.)

  5. Combine COPY statements, so instead of two COPY statements use only a single one. For this to work, the destination needs to be a folder. Additionally WORKDIR sets your current working directory, so any relative paths following that directive are relative to that directory. (That way you don't have to specify /app when copying the Gemfile, but simply copy it to ./

  6. Combine multiple RUN statements that are logically connected to generate fewer layers

  7. Switch from ADD to COPY for the remaining files. ADD should only be used in case you need the special behavior it provides (around downloading remote files or extracting archives), which is not the case for most Dockerfiles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment