DMCA.com Protection Status Trending Topics About Devops: Docker 101: Fundamentals & The Dockerfile

Tuesday, 9 March 2021

Docker 101: Fundamentals & The Dockerfile

Image for post
  • Docker Compose, and
  • Docker Swarm

What is Docker?

The Docker website itself simply describes Docker as:

Why Docker?

I can’t tell you how many times I’ve heard a developer (myself included) say, “It works on my machine, I don’t know why it won’t work on yours.” — any developer, ever

Image for post
The Docker container’s just like Jon Snow when it spins up; it knows nothing.

Docker Tools

Before I dive into the Dockerfile, I’ll give a quick run down of Docker’s suite of tools.

Image for post

The Dockerfile — where it all begins

Docker is a powerful tool, but its power is harnessed through the use of things called Dockerfiles.

Dockerfile Commands

Below, are the commands that will be used 90% of the time when you’re writing Dockerfiles, and what they mean.

  • RUN — 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 in the Dockerfile.
  • ENV — 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.
  • EXPOSE — informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified. This makes it possible for the host and the outside world to access the isolated Docker Container
  • VOLUME — creates a mount point with the specified name and marks it as holding externally mounted volumes from the native host or other containers.

Dockerfile Examples

Here are a few sample Dockerfiles, complete with comments explaining each line and what’s happening layer by layer.

# creates a layer from the node:carbon Docker image
FROM
node:carbon
# create the app directory for inside the Docker image
WORKDIR /usr/src/app
# copy and install app dependencies from the package.json (and the package-lock.json) into the root of the directory created above
COPY package*.json ./
RUN
npm install
# bundle app source inside Docker image
COPY . .
# expose port 8080 to have it mapped by Docker daemon
EXPOSE 8080
# define the command to run the app (it's the npm start script from the package.json file)
CMD [ "npm", "start" ]
# 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"]
# 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
# creates a layer from the jenkins:lts Docker image
FROM
jenkins/jenkins:lts
# sets user to root (because Docker always runs as root and Jenkins needs to know this)
USER root

# add and install all the necessary dependencies
RUN apt-get update && \
apt-get install -qy \
apt-utils \
libyaml-dev \
build-essential \
python-dev \
libxml2-dev \
libxslt-dev \
libffi-dev \
libssl-dev \
default-libmysqlclient-dev \
python-mysqldb \
python-pip \
libjpeg-dev \
zlib1g-dev \
libblas-dev\
liblapack-dev \
libatlas-base-dev \
apt-transport-https \
ca-certificates \
zip \
unzip \
gfortran && \
rm -rf /var/lib/apt/lists/*

# install docker
RUN curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh

# install docker compose
RUN curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && \
chmod +x /usr/local/bin/docker-compose
# install pip for python
RUN pip install cffi --upgrade
RUN pip install pip2pi ansible==2.0

# copy groovy executors and plugins for jenkins and run the plugins
COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/executors.groovy
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/ref/plugins.txt

# add the jenkins user to the docker group so that sudo is not required to run docker commands
RUN groupmod -g 1026 docker && gpasswd -a jenkins docker
USER jenkins

Images vs. Containers

The terms Docker image and Docker container are sometimes used interchangeably, but they shouldn’t be, they mean two different things.

Image for post
Examples of Docker containers. Each one comes from a specific Docker image.

Docker Engine Commands

Once the Dockerfile has been written the Docker image can be built and the Docker container can be run. All of this is taken care of by the Docker Engine that I covered briefly earlier.

Image for post
The CLI uses the Docker REST API to control or interact with the Docker daemon through scripting or direct CLI commands. Many other Docker applications use the underlying API and CLI as well.
  • docker images — displays all Docker images on that machine
  • docker run — starts container and runs any commands in that container
  • there’s multiple options that go along with docker run including
  • -p — allows you to specify ports in host and Docker container
  • -it—opens up an interactive terminal after the container starts running
  • -v — bind mount a volume to the container
  • -e — set environmental variables
  • -d — starts the container in daemon mode (it runs in a background process)
  • docker rmi — removes one or more images
  • docker rm — removes one or more containers
  • docker kill — kills one or more running containers
  • docker ps — displays a list of running containers
  • docker tag — tags the image with an alias that can be referenced later (good for versioning)
  • docker login — login to Docker registry

Conclusion and Part Two: Docker Compose

Now you’ve seen the tip of the iceberg of Docker. It’s a lightweight, isolated runtime environment known as a ‘container’ that you can spin up and configure just about anyway you like with the help of a Dockerfile.

No comments: