Docker Learning Note (iii)

This is a series blogs about Docker and Kubernetes — This is the 3rd blog following up to my last one.
In last blog, we discuss about building images step by step and introduce some popular commands.
Commands
Below, are most used commands when you’re writing Dockerfiles:
FROM <image>
— this initializes a new build and sets the Base Image. It must be the first non-comment instruction in the Dockerfile.RUN [“<executable>”, “<param1>”, “<param2>”] ||RUN <command>
— will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step. Note that this is a shell command, which is/bin/sh -c
on Linux orcmd /S /C
on Windows.ENV <key> <value>
— sets the environment variable<key>
to the value<value>
. This value will be in the environment for all subsequent instructions in the build stage and can be replaced inline in many as well.ARG <name>[=<default value>]
— Defines a variable that users can pass at build-time to the builder with thedocker build
command using the--build-arg <varname>=<value>
flag. Multiple variables may be defined by specifyingARG
multiple times. Note that Environment variables defined using theENV
instruction always override anARG
instruction of the same nameEXPOSE <port> [<port> …]
— informs Docker that the container listens on the specified network ports at runtime.This makes it possible for the host and the outside world to access the isolated Docker ContainerADD <src> [<src> …] <dest>
— copies new files, directories, or remote file URLs from<src>
and adds them to the filesystem of the image at the path<dest>
. Note that<dest>
is an absolute path, or a path relative toWORKDIR
COPY <src> [<src> …] <dest>
— copies new files or directories from<src>
and adds them to the filesystem of the image at the path<dest>
.
Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD. COPY only supports the basic copying of local files into the container, while ADD has some features (like local-only tar extraction and remote URL support) that are not immediately obvious. Consequently, the best use for ADD is local tar file auto-extraction into the image, as in ADD rootfs.tar.xz /. — Docker Best Practice
the <src>path must be inside the context of the build; When you run a
docker build .
, files in the folder.
that are not included inside the.dockerignore
file are sent to the Docker engine. From this context of files, docker performs the COPY or ADD commands. The<dest>
is an absolute path, or a path relative toWORKDIR
, into which the source will be copied inside the destination container.
VOLUME ["<path>", ...]
— creates a mount point with the specified name and marks it as holding externally mounted volumes from the native host or other containers.WORKDIR </path/to/workdir>
— sets the working directory for anyRUN
,CMD
,ENTRYPOINT
,COPY
, andADD
instructions that follow it. It can be used multiple times in the one Dockerfile. If a relative path is provided, it will be relative to the path of the previousWORKDIR
instruction.CMD [“<executable>”,”<param1>”,”<param2>”]
— provides defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify anENTRYPOINT
instruction as well. Note that there can only be oneCMD
in one Dockerfile, and usingdocker run
will override the default specified inCMD
ENTRYPOINT [“<executable>”, “<param1>”, “<param2>”]
— allows you to configure a container that will run as an executable.IfCMD
is used to provide default arguments for theENTRYPOINT
instruction, both theCMD
andENTRYPOINT
instructions should be specified with the JSON array format.USER —
The USER instruction is used to define the default user or gid when running the image. The RUN, CMD, and ENTRYPOINT follow the USER instruction in the Dockerfile.
Examples
Node
FROM node:10-alpine
# create the app directory for inside the Docker image
WORKDIR /usr/src/app
# copy the package.json and package-lock.json into the root directory, we do this separately with COPY in the next step is to utilise docker cache
COPY package*.json ./
#install app dependencies
RUN npm install
# bundle app source inside Docker image
COPY . .
# expose port 8080
EXPOSE 8080
# define the command to run the app, in this case it's the npm start script from the package.json
CMD [ "npm", "start" ]
Java
# creates a layer from the openjdk:8-jdk-alpine Docker image
FROM openjdk:8-jdk-alpine
# create the directory for where Tomcat creates its working directories
VOLUME /tmp
# copy the project JAR file to the container renamed as 'app.jar'
COPY build/libs /app
# execute that JAR in the entry point below
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/java-example.jar"]
Python Dockerfile Example
# creates a layer from the ubuntu:16.04 Docker image
FROM ubuntu:16.04
# adds files from the Docker client’s current directory
COPY . /app
# builds the application with make
RUN make /app
# specifies what command to run within the container
CMD python /app/app.py
You can also build multi-stage Docker file like:
//stage 1
FROM node:alpine as builder
WORKDIR ‘/app’
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build//stage 2
FROM nginx
EXPOSE 80
COPY — from=builder /app/build /usr/share/nginx/html
# copy the build folder to this /usr/share/nginx/html
Dockerignore
To keep your Docker image as small as possible, packaging only what is needed in your image. But in our app directory, we often have some files that are irrelevant to our final build.
It’s a best practice not to have them in your image — that’s what .dockerignore is for. It’s just like .gitignore
:
.git
.gitignore
node_modules
Dockerfile*
docker-compose*
README.md
LICENSE
So that’s so much of it today! Happy Reading :).
🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊🐬 🐳 🎽 ❄️ 💦 🌊