Getting to Know Dockerfile Instructions: Part 4

  1. A review of several snippets of Dockerfiles found at https://hub.docker.com
  2. You build a demo Dockerfile that summarizes insights from these snippets
  3. Dockerfile glossary summary texts
  4. Summary of Dockerfile best practices

Review of Snippets of Dockerfiles — EXPOSE

# 7000: intra-node communication
# 7001: TLS intra-node communication
# 7199: JMX
# 9042: CQL
# 9160: thrift service
EXPOSE 7000 7001 7199 9042 9160
CMD ["cassandra", "-f"]

Review of Snippets of Dockerfiles — User IDs

# explicitly set user/group IDs
RUN groupadd -r cassandra --gid=999 && useradd -r -g cassandra --uid=999 cassandra
RUN groupadd -r sonarqube && useradd -r -g sonarqube sonarqube
RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j
RUN addgroup -S neo4j \
&& adduser -S -H -h /var/lib/neo4j -G neo4j neo4j

Review of Snippets of Dockerfiles — apt-get Install

RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
rsync \
bzip2 \
busybox-static \
; \
rm -rf /var/lib/apt/lists/*; \
RUN apt-get update && \
apt-get install -y \
curl procps \
&& rm -rf /var/lib/apt/lists/*
# install plugin dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
apt-transport-https \
libzmq5 \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends \
bzip2 \
unzip \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
RUN apk add --no-cache --quiet \
bash \
curl \
tini \
su-exec \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -csw - \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* /var/lib/neo4j \
&& rm ${NEO4J_TARBALL} \
&& mv /var/lib/neo4j/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /var/lib/neo4j \
&& chmod -R 777 /var/lib/neo4j \
&& ln -s /data /var/lib/neo4j/data \
&& apk del curl

Review of Snippets of Dockerfiles — ini Files

RUN { \
echo 'opcache.enable=1'; \
echo 'opcache.enable_cli=1'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini; \
\
echo 'apc.enable_cli=1' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini; \
\
echo 'memory_limit=512M' > /usr/local/etc/php/conf.d/memory-limit.ini; \
\
mkdir /var/www/data; \
chown -R www-data:root /var/www; \
chmod -R g=u /var/www

Review of Snippets of Dockerfiles -

FROM openjdk:8-jdkRUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG http_port=8080
ARG agent_port=50000
ENV JENKINS_HOME /var/jenkins_home
ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
'# Jenkins is run with user `jenkins`, uid = 1000
'# If you bind mount a volume from the host or a data container,
'# ensure you use the same uid
RUN groupadd -g ${gid} ${group} \
&& useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}

'# for main web interface:
EXPOSE ${http_port}
'# will be used by attached slave agents:
EXPOSE ${agent_port}
  1. ARG names all lower case
  2. ARG names sorted by function: user + group; uid + guid; 2 ports
  3. ENV names all upper case
  4. groupadd and useradd over 2 lines
  5. useradd aligns perfectly with groupadd

Review of Snippets of Dockerfiles — RUN

ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin
ENV PGDATA /var/lib/postgresql/data
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
VOLUME /var/lib/postgresql/data
RUN mkdir -p "$PGDATA" \
&& chown -R postgres:postgres "$PGDATA" \
&& chmod 777 "$PGDATA" \
# this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)

Review of Snippets of Dockerfiles — Sorted apt-get Install

'# install httpd runtime dependencies
'# https://httpd.apache.org/docs/2.4/install.html#requirements
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libapr1 \
libaprutil1 \
libaprutil1-ldap \
libapr1-dev \
libaprutil1-dev \
liblua5.2-0 \
libnghttp2-14=$NGHTTP2_VERSION \
libpcre++0 \
libssl1.0.0=$OPENSSL_VERSION \
libxml2 \
&& rm -r /var/lib/apt/lists/*
RUN apt-get update 
&& apt-get install -y --no-install-recommends \
libxml2 \
libaprutil1 \
libnghttp2-14=$NGHTTP2_VERSION \
libapr1-dev \
liblua5.2-0 \
libaprutil1-dev \
libpcre++0 \
libapr1 \
libssl1.0.0=$OPENSSL_VERSION \
libaprutil1-ldap \
&& rm -r /var/lib/apt/lists/*

Building a Demo Dockerfile

FROM 
COPY
ADD
RUN
LABEL
EXPOSE
ENVIRONMENT
ENTRYPOINT
VOLUME
USER
WORKDIR
ARG

Dockerfile Concepts

Summary of Dockerfile Best Practices

  1. Have a small build context … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#understand-build-context
  2. Use dockerignore … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#exclude-with-dockerignore
  3. Minimize the number of layers … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers
  4. Sort multi-line arguments … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#sort-multi-line-arguments
  5. Use Alpine FROM … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from
  6. Add one label — just for practice … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#label
  7. Split long or complex RUN statements onto multiple lines — see examples above … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run
  8. Expose any port — just for practice … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#expose
  9. Define some ENV variables … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#env
  10. Use ADD and COPY to show you understand their differences …https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy
  11. Define a VOLUME … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#volume
  12. Add a demo test user — many examples at top of this tutorial …https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
  13. Create a workdir … https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#workdir

Your Turn

--

--

--

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

AWS EC2: Exploring Instance Types

How to implement a Fluid Simulation on the CPU with Unity (ECS/Job System)

How to use LandscapeEdMode tools in Unreal Engine

Dedicated Development Team

The magical answer for software development project management

How to implement rapid deployment of SequoiaDB cluster with Docker

I Got Better With Money When I Rejected My Conservative, Working Class Roots

Sea World Itinerary

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

More from Medium

Setting up Kafka on Kubernetes - an easy way

Kafka on GCP Cluster

Benchmark Our Redis Cluster

Deploying Airflow in Local Kubernetes Cluster: Part II