Sample Docker Files

Dockerfile Commands

A list of common Dockerfile commands are provided below:

  • RUN executes any command in a new layer on top of the current image and commits the results. Layering RUN instructions and generating commits conforms to the core conept of Docker where commits are cheap and containers can be created from any point in an image’s history, making containers work like source control.

  • ENTRYPOINT allows you to configure a container which has a default executable and execute that executable.

  • CMD provides defaults (commands or command parameters for an ENTRYPOINT) for a container.

  • ARG Is only available during the build of Docker image and not after the image is created..

  • ENV These are values available to containers and also to RUN style commands during the Docker build.

  • .env file Is a convenient way to define all dollar notation variables like $ABC in a file and is only used during the pre-processing steps when working with docker-compose .yml files.

  • env_file Is a convenient way to pass many environment variables to a single command in one batch and is different from the .env file.

NGINX Web Server

FROM nginx:stable
COPY ./html/ /usr/share/nginx/html
# COPY ./default.conf /etc/nginx/config.d/
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
  • Given above is a sample of the Dockerfile used to run an nginx web server.

  • We use $ docker build -t thomaspk/tom-web:latest . to build this docker image.

Single stage Docker build

1FROM openjdk:11-slim-buster
2COPY target/spring-jpa-0.0.1-SNAPSHOT.jar /opt/
3ENTRYPOINT ["java"]
4CMD ["-jar", "/opt/spring-jpa-0.0.1-SNAPSHOT.jar"]
5EXPOSE 8080

The above Dockerfile takes a compiled and packaged jar file and runs it in an openjdk 11 debian buster image.

Multi-stage Docker builds

 1# Create a transient container to build the application
 2FROM maven:3-jdk-11-slim AS java-build
 3WORKDIR /app-build/
 4COPY pom.xml .
 5
 6# Download all dependencies for this maven project so that it doesn't have to
 7#   download it everytime we do a docker build.
 8# RUN mvn clean
 9RUN mvn dependency:go-offline
10
11# Copy source code over as they change more than the maven packages
12COPY src src
13RUN mvn package     # Package the maven packages and compiled code into a jar
14
15# Prepare the final runtime image
16FROM openjdk:11-jre-slim
17# FROM gcr.io/distroless/java:11
18COPY --from=java-build /app-build/target/*.jar /app/app.jar
19EXPOSE 8080
20ENTRYPOINT ["java"]
21CMD ["-jar","/app/app.jar"]
  • The Dockerfile above shows a multistage build denoted by the second FROM, which means the first FROM build is a temporary build to compile the code.

  • The sequence of docker commands is ordered from least likely to change to most likely to change.

  • As each docker command create a new layer, this allows preceding layers that haven’t changed much to remain the same, while only the changed layers are downloaded for a new image build.

Kubernetes Container Command over-ride

This section shows how a command running on a docker image can be over-ridden in Kubernetes.

FROM debian:stable
ENTRYPOINT ["sleep"]
CMD ["5"]
  • If we issue $ docker build -t thomaspk/debian-sleeper . and then $ docker run thomaspk/debian-sleeper, it will run the docker file shown above and execute the sleep command for 5 seconds.

  • Now issue $ docker push thomaspk/debian-sleeper to push this image to the docker hub.

1apiVersion: v1
2kind: Pod
3metadata:
4name: debian-sleeper-pod
5spec:
6containers:
7- name: debian-sleeper
8  image: debian-sleeper
9  args: ["10"]
  • If we build and push the previous Dockerfile shown above to docker hub and used the above Kubernetes yaml file to pull and run the image, it would sleep for 10 seconds instead of the default 5 seconds defined in the Dockerfile.