From Skeptic to Believer: My Docker Story
Tags: docker, containers
Published: 2024-03-13 08:29:08

## Introduction

The first time I heard about Docker was about 2 years ago. Over the last two years, I have read various articles and watched various tutorials on how to use Docker but have never really felt the need to install or use it. I however started a new job as a backend developer a month ago and docker became an essential part of my workflow so I had no option but to download and set it up.

In this article, I will share my brief experience with Docker. I will also delve into key Docker concepts, such as images and containers, and highlight some of the most useful Docker commands I've come across and used so far.

## My Experience with Docker So Far

Aside from the initial hurdle of setting up Windows Subsystem for Linux (wsl) as well as a few issues with authentication on docker hub, Using docker has been quite pleasant. So pleasant that I currently do not have any database installed locally anymore. A week into playing around with docker, I uninstalled Postgres, MongoDB, MySQL, and Neo4j. Whenever I need a database running locally now, I just create a container from one of the several images I downloaded locally.

Before I go further, I would also like to say that one of the major issues I had was distinguishing between Docker images and Docker containers. However, an explanation I read on the geeks for geeks website pretty much cleared it up. 

`The concept of Image and Container is like a class and object, in which an object is an instance of a class, and a class is the blueprint of the object.` 

I know it is a little bit more complicated than that, but this simple explanation gave me the foundation I needed to understand the difference between both concepts.

## Other Important Docker Concepts

Some other important docker concepts include:

* **Dockerfile**: A dockerfile is a text document with instructions on how to build a docker image. A dockerfile is like a recipe that defines all the steps needed to create a Docker image, such as installing dependencies, setting up environment variables, copying files, and configuring the container. An example of a dockerfile that defines instructions to create a Docker image for a Python application, installing dependencies, exposing port 8080, setting an environment variable, and running the application when the container starts is shown below.

```
# Use a base image
FROM python:3.9-slim

# Set the working directory in the container to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install dependencies from requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Expose port 8080
EXPOSE 8080

# Define environment variable
ENV ENVIRONMENT production

# Run the application when the container launches
CMD ["python", "app.py"]

```

* **Docker Daemon**: This is the background process that is responsible managing docker objects such as images, containers, networks, and volumes. The Docker daemon exposes an API that allows users and client applications to issue commands and interact with Docker.

## My Most Used Docker Commands

So we have come to arguably the most important part of this article. Here I am going to be listing my most used or important Docker commands. 

Side Note: This is not an exhaustive list.

* `docker --version`: Displays the current version of Docker installed on your system. It's what I use to quickly check if docker is running.

* `docker pull <image>`: Downloads a Docker image to your local machine e.g. `docker pull mongo` pulls the latest official mongo image from docker hub.

* `docker image ls`: Lists all Docker images currently stored on your local machine.
 
* `docker ps`: Lists all running Docker containers.
 
* `docker ps -a`:: Lists all Docker containers, including those that are not currently running.
  
* `docker start <container_name>` or `docker start <container_id>`:  Starts a stopped Docker container with the specified container name or ID.

* `docker stop <container_name>` or `docker start <container_id>`:  Stops a running Docker container with the specified container name or ID.
 
* `docker run --name postgres_db -p 5432:5432 -e POSTGRES_PASSWORD=password postgres -d`: Creates and starts a new Docker container named "postgres_db" running PostgreSQL and exposing port 5432 on the host machine, sets the environment variable POSTGRES_PASSWORD to "password", and runs the container in detached mode (-d). 

**NB:** Running a container in detached mode means that the container runs in the background, and the terminal prompt is returned to you immediately after starting the container. This allows you to continue using the terminal for other tasks while the container runs in the background.

* `docker run --name mongo_db -p 27017:27017 mongo -d`: Creates and starts a new Docker container named "mongo_db" running MongoDB and exposing port 27017 on the host machine, and runs the container in detached mode (-d). 

## Conclusion

In conclusion, my journey with Docker has been nothing short of interesting. What initially seemed like a daunting tool to learn has quickly become an essential part of my development workflow. 

As I continue to explore and expand my knowledge of Docker, I am excited about the possibilities it presents. I look forward to incorporating Docker into more projects and leveraging its capabilities to build robust and scalable applications.