Skip to content

Instantly share code, notes, and snippets.

@pdonorio
Last active June 25, 2022 19:20
Show Gist options
  • Save pdonorio/9222ea7e8544a60c2910f087cdb8e9e0 to your computer and use it in GitHub Desktop.
Save pdonorio/9222ea7e8544a60c2910f087cdb8e9e0 to your computer and use it in GitHub Desktop.
Dockerfile best practices

Dockerfile best practices

A set of best practices for creating a better container image with Docker.

# build
$ docker build -t myimage .
# see layers
$ docker history myimage
# test
$ docker run --rm -it myimage echo hello
# tag and push
$ docker tag myimage dockerhubuser/imagename:imageversion
$ docker push dockerhubuser/imagename:imageversion
###################
# 1. start with a small image (e.g. alpine OS)
FROM alpine:3.7
# or with the 'alpine' version of the official build
# FROM nginx:1.13.9-alpine
# 2. fix a tag to image version
###################
# 3. Provide info about who you are
LABEL maintainer="Paolo D'Onorio De Meo <[email protected]>"
###################
# 4. Parametric decision from outside variables
ARG RAPYDO_VERSION
# NOTE: make the parameter required
RUN test -n "$RAPYDO_VERSION"
RUN mkdir -p /etc/rapydo && echo $RAPYDO_VERSION > /etc/rapydo/release
###################
# 5. Chained commands to avoid extra space
RUN apk update && \
apk add vim wget git bash \
openssl curl netcat-openbsd \
tini \
&& rm -rf /var/cache/apk/*
###################
# 6. Set the working dir inside the build to a temporary directory
WORKDIR /tmp
###################
# 6. Set fixed versions also for installed tools
ENV ACMEV "2.7.6"
RUN wget https://github.com/Neilpang/acme.sh/archive/${ACMEV}.zip \
&& unzip ${ACMEV}.zip && cd acme.sh-${ACMEV} \
&& ./acme.sh --install --home /opt/acme \
&& cd .. && rm -rf *$ACMEV
#######################
# 7. Do not use root as user
ENV GUEST_USER developer
ENV GUEST_UID 1001
# # NOTE: you can map the user to the one who builds the image
# ARG CURRENT_UID
# RUN test -n "$CURRENT_UID"
# ENV GUEST_UID $CURRENT_UID
ENV GUEST_SHELL /bin/bash
ENV GUEST_HOME /home/$GUEST_USER
RUN adduser -s $GUEST_SHELL -u $GUEST_UID -D -d $GUEST_HOME $GUEST_USER
###################################
# 8. Run an entrypoint script as main container command
RUN mkdir /docker-entrypoint.d
COPY ./entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/*
# NOTE: tini (installed previously) helps handling container failures
ENTRYPOINT ["/sbin/tini", "docker-entrypoint"]
# NOTE: as non privileged user from previous
CMD ["mycmd"]
#######################
# Switch to the new user
USER $GUEST_USER # TODO: Has to happen before CMD/ENTRYPOINT ?
WORKDIR $GUEST_HOME
# 8. set bash variables to a more comfortable experience in debugging
ENV PAGER less
ENV TERM=xterm-256color
ENV HISTCONTROL ignoreboth:erasedups
# Fix problems with incompatible shell sizes
ENV LINES 28
ENV COLUMNS 160
###################################
# 10. expose ports to other containers of the same network
# EXPOSE 8080
###################################
# 11. Persistence
# VOLUME /var/lib/mytool
#!/bin/bash
set -e
#####################
# Extra scripts
dedir="/docker-entrypoint.d"
for f in `ls $dedir`; do
case "$f" in
*.sh) echo "running $f"; bash "$dedir/$f" ;;
*) echo "ignoring $f" ;;
esac
echo
done
#####################
# Different runtime command
if [ "$1" != 'client' ]; then
echo "Custom command:"
echo "\$ $@"
$@
exit 0
#####################
# Main command
else
echo "Just a test"
# USE CREDENTIALS
# e.g. docker run --rm -it -e USERNAME=test PASSWORD=beta myimage
mytool -u $USERNAME -p $PASSWORD
exit 0
fi
@merretbuurman
Copy link

Good morning,
I tried to push my corrections to your gist, but I do not have permissions, and PRs are not possible on gists (https://stackoverflow.com/questions/8758612/can-i-make-a-pull-request-on-a-gist-on-github), so maybe you could update your gist from my fork...

@pdonorio
Copy link
Author

pdonorio commented Apr 5, 2018

Updated from your fork, thanks!

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