Docker container - Basics

A Container is a box in which our application runs, with all things it requires (dependencies) to run. Docker is one of the tools used to build & manage these containers.

Real-world example

Flow - { Dockerfile -> Docker Image -> Docker container }

Before we start, let's understand the above flow with an example.

Imagine you plan to cook chicken biryani by yourself. Since we are not magicians, we need to have a plan before we even start cooking. So let's list down the steps -

  1. You need to list down all the things required to prepare your food.

  2. Now you need to assemble it properly, so that, you can cook it.

  3. After this, you can start cooking.

Dockerfile

The first step above is your Dockerfile. Here you list down the things required for you so that your application runs smoothly.

A few keywords are -

  1. FROM - Used to download any package you need.

  2. ADD - To add/copy your application directory inside the container.

  3. RUN - To execute any commands, before starting your application.

    Eg. If you want the timezone inside your container to be IST by default, then those commands can be written here.

  4. CMD - Default command to start the container. Here you write the command to run your Application. The important thing is your container will immediately terminate if the command in CMD doesn't work as expected.

    Eg. Your Application doesn't startup properly.

Docker Image

The second step in the above flow is your Docker Image. Here you build your Dockerfile.

docker build -t Image-name .

-t -> Used to denote the Docker Image name

. -> Dot is used because my dockerfile is in my current directory.

To list down all images -

docker images

Docker Images provides you with a layer-like structure, where each layer is the line you wrote above in your Dockerfile. It's used for reusability, if a layer is already present then it won't get it again.

Docker Container

Now finally, we will build our containers. The third step in the above flow is this.

docker run -itd \
-p 5001:5001/tcp \
--restart on-failure:5 \
-v server-directory-path:container-directory-path \ 
--name container-name \
image-name

-it -> Used for getting Interactive terminal sessions by default inside containers.

-d -> To run your container in the background.

-p -> To Publish / Expose Ports. Exposing ports in your docker file only act as documentation, & actual exposing ports happen using the -p or --publish flag in the docker run command.

Why did I add 5001?

  • Because I wanted to send any traffic coming to Port 5001 on my server to my container's port 5001, my application runs at 5001 port.

--restart -> Tells it when it should restart the containers, automatically & how many times it should try.

Why did we add a restart policy here?

  • If our application running inside the container is not able to make a database connection at first attempt, it should try again.

-v -> To add a Volume.

Why did we do this?

  • We wanted everything inside our container directory (mainly logs) to be present in our server's directory as well. If your container terminates, then you won't lose any log files.

--name -> Assign a name to our container

And finally the most important thing, we have to mention which Docker Image, should be used to create this container.

Now, check the running containers using -

docker ps

To get a list of Both running & stopped containers -

docker ps -a

Another important thing is debugging if your container exits/stops. So for that -

docker logs container-id

Note:- There can be cases, where your docker logs are empty, which means your CMD (default command) hasn't run.

Containers are your long-term investment, like equity or mutual funds...Good luck on your container journey.