What are Docker containers?

Docker containers are a smaller version of Virtual Machines with farless overheads and lot for flexibility. If you want to isolate different services on your system then you can make multiple dockers images for each service and run them, separately.

How it works?

Well all you need to do is make a file named Dockerfile which would contain the rules/instructions of what all has to be done in that container and then you start the build of your container.

We’ll learn how to write Dockerfile shortly but before that let us dicuss some commands that are used to start/stop/build docker image.

Installation

Just install docker using the package manager of your OS and then start the docker.service(if not already running.)

  • To start the docker.service
systemctl start docker.service

General Commands for docker

  • When you are in a directory containing Dockerfile run
docker build .

This will build your Docker image.

  • To check all the existing docker images run
docker images
  • To see all the docker process:
docker ps -a

This will show you all the running and exited docker process.

  • To stop the container:
docker stop <container-id>
  • To kill a process:
docker kill <name-of-the-process>
  • To remove the docker process
docker rm <name-of-the-process>

Note: Make sure to kill the process before you try to remove it.

  • To remove the docker image
docker rmi <image-id>

Note: Make sure that you’ve removed the process that was using that image.

  • To commit changes to the container:
docker commit <container_id>

This is for when you make changes to some image you might have pulled from dockerhub and then would like to save those changes to a new image.

These are the most commonly used docker commands. Obviously there are lot of other commands which you can read about either by running man docker or docker --help

Creating Dockerfile

Knowing all the docker command might not be enough to be able to play with this weirdly awesome technology. One of the important thing in docker is Dockerfile which contains all instructions that will be followed in order to build the container.

Here are the most commonly used Dockerfile instructions:

  • FROM: This is the first non-comment instruction in the Dockerfile. Usually the syntax is FROM <images>:<tag>. So if we want to make an image for ubuntu 16.04 we’ll write FROM ubuntu:16.04. If we are going to do just FROM ubuntu then it would take the latest version of ubuntu to build the image.

  • ENV: This is used in the dockerfile to set any environment variable.

`ENV user=root`

Here we are making an environment variable named user with value root so then later in the Dockerfile we can use $user to refer to the user root.

  • RUN: This command is used, obviously to run any command you want. We can also run a script using the RUN command. The format to run a script is RUN ["<executable>", "<param1>", "<param2>"] (exec form).
`Run mkdir /home/mzfr`.
  • COPY: Using this instruction you can copy any file from your local system to docker image. Say you have a script name hack.py in your /tmp folder and what that to be present in /home/mzfr/ in your docker image so you can write the following in the docker image
COPY /tmp/hack.py /home/mzfr/hack.py
  • Expose: This informs Docker that the container listens on the specified network port(s) at runtime.
EXPOSE 22
  • ADD: Add is very similar to COPY the only difference is that in ADD instruction also supports remote file URL.

  • WORKDIR: This sets the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that follows it.

  • USER: This instruction sets the user name to use when running the image and for any RUN, CMD instructions that follow it in the Dockerfile.

USER root
RUN whoami

This will give root as the output because before running whoami you set user as root. We can also say that this let us execute commands as different users.

These are almost 90-95% of the command that I’ve ever used in writing my Dockerfiles.

Examples

Now we’ll see some examples of Dockerfile so you’ll have a better idea of what is happening and how it’s done.

Example 1

# ubuntu 16.04 docker image
FROM ubuntu:16.04
# set environment variable "user" with value "hacker"
ENV user=hacker
# get updates
RUN apt-get update
# install openssh
RUN apt-get install -y openssh-server
# install lshell
RUN apt-get install -y lshell
# Make a directory
RUN mkdir /var/run/sshd
# add a new user named "hacker"
RUN useradd -m $user
# copy a file from CWD to the specified docker directory
COPY ./hack.py /home/$user/hack.py

RUN chmod +x /home/$user/me/hack.py
RUN chown -R root:$user /home/$user
RUN chmod -R 750 /home/$user
RUN chsh -s /usr/bin/lshell hacker
RUN echo "hacker:passwd" | chpasswd

COPY ./lshell.conf /etc/lshell.conf

# Expose port 22 so when docker run it is accesible on 22
EXPOSE 22
# Run a SSH daemon with -D arg
CMD ["/usr/sbin/sshd", "-D"]

Example 2

FROM python:3

# update. upgrade. Install xinetd
RUN apt-get update --fix-missing && apt-get install -y xinetd
# Add a new user group and a new user to that group
RUN groupadd -r ctf && useradd -r -g ctf ctf
# Set the working directory for the next commands
WORKDIR /usr/src/app
# Copy the content of src folder from file system to docker /usr/src/app
COPY ./src .
RUN pip install --no-cache-dir -r requirements.txt

# Configuration files/scripts
ADD config/ctf.xinetd /etc/xinetd.d/ctf
ADD config/run_xinetd.sh /etc/run_xinetd.sh
ADD config/run_challenge.sh /run_challenge.sh

RUN chmod +x /run_challenge.sh
RUN chmod +x /etc/run_xinetd.sh

#start the xinetd service
RUN service xinetd restart

That’s all for now, hope this will help you in understanding Docker.

Thanks for reading, feedback is always appreciated.

You can follow me on @0xmzfr.