Skip to content
Search

Dockerfile

lastmod 2025-04-11created 2015-12-0931 edits

Notes on Dockerfile.

Examples

Build

Build a Dockerfile as follows.

$ docker build -t [REPO_NAME]/[TAG_NAME] [DOCKERFILE_PATH]

Command

  • FROM: Specifies the parent image, that is, which image the new image is created from.
  • MAINTAINER: Information about the person who creates and maintains the Dockerfile.
  • ENV: Sets environment variables.
  • EXPOSE: Specifies the ports to open on the virtual machine. Same as the --expose option of the docker run command.
  • WORKDIR: Sets the working directory in which commands are run.
  • ADD: Adds files to the image. The format is ADD [복사할 파일 경로] [이미지에서 파일이 위치할 경로] (source file path, destination path in the image).
    • It is good practice to verify files added with the ADD instruction with a hash-based checksum.
  • CMD: Specifies the command to run in the container. However, it is not run if COMMAND is given in docker run [OPTIONS] IMAGE [COMMAND] [ARG...].
    • Only needed in special cases, such as building a base image containing an operating system.
    • It doesn't guarantee stability, so use COPY instead.
  • ENTRYPOINT: Similar to CMD. However, if COMMAND is given in docker run [OPTIONS] IMAGE [COMMAND] [ARG...], it is appended as additional arguments to ENTRYPOINT. 1
  • Volume: In short, directory sharing.
  • RUN: Defines commands to run in the container when building the image
  • COPY: Copies files and directories from the host to the container
  • ARG: Variables used when running docker image build
  • EXPOSE: Ports the container exposes
  • VOLUME: Creates a point that the host or other containers can mount
  • LABEL: Metadata added to the image
  • STOPSIGNAL: Sets the system signal that stops the container when sent to it
  • HEALTHCHECK: Runs a command inside the container and uses the result for health checks
  • USER: The container user when the container runs
    • During the image build, RUN instructions after USER also run with that user's permissions.
  • ONBUILD: Defines commands run inside the container; they are not run in the image.
    • They run when another image is built using the image that defines ONBUILD as its base image.

Setup

You usually start as follows.

For CentOS 7:

FROM centos:7
MAINTAINER yourname <[email protected]>

For Ubuntu 14.04:

FROM ubuntu:14.04
MAINTAINER yourname <[email protected]>

Example

FROM ubuntu:12.04
MAINTAINER Daekwon Kim <[email protected]>
# COMMENT
RUN apt-get -qq -y install git curl build-essential
RUN apt-get -qq -y install apache2
ENV APACHE_RUN_USER www-data
# ...
RUN ./var/www/moniwiki/secure.sh
EXPOSE 80
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

ENV APP_HOME /myapp
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
ADD . $APP_HOME

Base images

scratch: An empty image
If HTTPS communication is needed, you must add cacert.pem to /etc/ssl/certs.
Debugging is hard, too
busybox: An image with basic utilities (echo, ls, etc.)
No package manager.
Debugging is somewhat better.
alpine: Based on busybox and only 4MB, but has the apk package manager.
Uses musl instead of glibc.
  • apk add --no-cache package
  • apk add --no-cache --virtual=ailas package && apk del --no-cache ailas
distroless images
Images focused on a language, without operating system features.
Available at distroless, and mostly distributed by Google.
The gcr.io/distroless/base image is glibc-based and suited to running compiled applications. (Go)
Contains only minimal libraries, such as ca-certificates and TLS/SSL-related libraries.
Reportedly, CVE vulnerabilities are also patched.

MySQL dockerfile

FROM ubuntu:14.04

## apt-get 설치시 사용자 입력을 받지 않는다는 환경변수 설정.
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update
RUN echo "mysql-server mysql-server/root_password password" | debconf-set-selections
RUN echo "mysql-server mysql-server/root_password_again password" | debconf-set-selections
RUN apt-get install -y mysql-server

WORKDIR /etc/mysql
RUN sed -i "s/127.0.0.1/0.0.0.0/g" my.cnf

Multi-stage build

Use a previous stage as a new stage

You can pick up where a previous stage left off by referring to it when using the FROM directive. For example:

FROM alpine:latest as builder
RUN apk --no-cache add build-base

FROM builder as build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp

FROM builder as build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp

Docker image build script

A bash script that builds an image for a project:

#!/usr/bin/env bash

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)
WORKING_DIR=$SCRIPT_DIR
DOCKERFILE_PATH=$SCRIPT_DIR/project-python-3.8.9.dockerfile
IMAGE_NAME=yourname/project
IMAGE_TAG=python-3.8.9
TAG_NAME=$IMAGE_NAME:$IMAGE_TAG
TAG_LATEST=$IMAGE_NAME:latest

USAGE_MESSAGE="
Build project docker image.

  Usage: project-build.sh [options]

Available options are:
  -p, --push    Push an image to a registry.
  -l, --latest  Add 'latest' tag.
  -n, --dry-run Don’t actually do anything, just show what would be done.
  -h, --help    Print this message.
"

function exit_on_error
{
    local code=$?
    if [[ $code -ne 0 ]]; then
        exit $code
    fi
}

function run_command
{
    local dry_run=$1
    shift

    if [[ $dry_run -eq 1 ]]; then
        echo "$@"
    else
        "$@"
    fi

    exit_on_error
}

function recc_node_build_main
{
    local src="$OPM_HOME/INFORMATION"
    local enable_push=0
    local add_latest=0
    local dry_run=0

    while [[ ! -z $1 ]]; do
        case $1 in
        -h|--help)
            echo "$USAGE_MESSAGE"
            return 0
            ;;
        -p|--push)
            enable_push=1
            shift
            ;;
        -n|--dry-run)
            dry_run=1
            shift
            ;;
        -l|--latest)
            add_latest=1
            shift
            ;;
        *)
            break
            ;;
        esac
    done

    local build_commands=("--file" "$DOCKERFILE_PATH" "-t" "$TAG_NAME")
    if [[ $add_latest -eq 1 ]]; then
        build_commands+=("-t" "$TAG_LATEST")
    fi
    build_commands+=("$WORKING_DIR")

    run_command $dry_run docker build ${build_commands[*]}
    if [[ $enable_push -eq 0 ]]; then
        return 0
    fi

    run_command $dry_run docker push $TAG_NAME
    if [[ $add_latest -eq 0 ]]; then
        return 0
    fi

    run_command $dry_run docker push $TAG_LATEST
}

recc_node_build_main "$@"

dockerd tuning

  • max-concurrent-downloads: Default is 3. Increases the number of image threads downloaded at once by docker image pull.
  • max-concurrent-uploads: Default is 5. Increases the number of image upload threads during docker image push.
  • registry-mirrors: Creating a mirror registry of Docker hub can help improve traffic.

Tools

See also

Favorite site

Examples

Guide

References


  1. Docker for the Really Impatient, Chapter 7 - 6. ENTRYPOINT ↩

  2. Docker_Best_Practices_for_Python_Developers_TestDriven.io.pdf ↩

author Zer0 sitemap