Docker Basics

Docker Basics

June 1, 2022

Docker is a platform that allows you to package and run software applications in a consistent and isolated environment called a container. It simplifies the process of deploying applications by providing a standardized way to package all the necessary dependencies, configurations, and code into a single unit that can run on any system.

$$ Dockerfile \overset{BUILD}{\ -\ -\ -\ ->} Image \overset{RUN}{\ -\ -\ -\ ->} Container $$

Basic Commands

Presented here is a Dockerfile, accompanied by essential comments, which serves as a fundamental component for containerization and streamlining application deployment processes within a Docker environment.

# Use the official Python 3.7 base image
FROM python:3.7
# Set the maintainer information
MAINTAINER "TechTalkVerse"
# Set the working directory inside the container
WORKDIR /usr/app
# Upgrade pip to the latest version
RUN pip install --upgrade pip
# Copy the requirements.txt file from the host to the container
COPY requirements.txt ./
# Install the Python dependencies specified in requirements.txt
RUN pip install -r requirements.txt
# Copy the entire current directory (including app.py) to the container
COPY . ./
# Expose port 5000 to allow external access
EXPOSE 5000
# Set the command to be executed when the container starts
ENTRYPOINT ["python3", "app.py"]

Build the above dockerfile - - > docker build -t image_tag .
Run the built image - - > docker run -p 5000:5000 image_tag

Image Commands

  • List all the images : docker images
  • Run an image to make a container : docker run image_name
  • Run an image to make a container with specifying container name : docker run --name container_name image_name
  • Run an image with -it flag to interact with container : docker run -it --name container_name image_name
  • Delete an image : docker image rm image_name
  • Delete all the images : sudo docker rmi -f $(sudo docker images -a -q)

Container Commands

  • List of running containers : docker ps
  • List of all containers : docker ps -a
  • Stop a container : docker stop container_id
  • Stop a container : docker stop container_name
  • Start a container : docker start container_name
  • Start a container in interactive mode : docker start --attach container_name
  • Delete a container : docker rm container_id
  • Delete all the containers : sudo docker rm `sudo docker ps --no-trunc -aq`

Volume Mounting

  • Persistent Volume Mounting
    By using volume mounting, the data generated by the container will be persisted outside the container, in the local filesystem of the host machine. This allows the data to be preserved even if the container is stopped or restarted.

    docker volume create my_volume
    docker run -v my_volume:/path/to/mount my_image
  • Non-Persistent Volume Mounting
    Non-persistent volume mounting involves mounting directories or files from the host machine directly to the container, without creating a named volume. Non-persistent volume mounts are typically used for sharing configuration files, running one-time data processing tasks, or temporary data exchange.
    docker run -v <host_directory>:<container_directory>:<options> <image_name>
    can include settings such as read-only access (ro) or mounting a single file instead of a directory.

Interacting with Container

  • Interact with running container
    docker exec -it mycontainer sh
    The options -it allocate a pseudo-TTY and keep STDIN open to allow interactive shell access. A TTY is a terminal emulation device that allows input and output between a user and a computer program The command sh specifies the shell command to execute inside the container.

  • Interact with stopped container
    Interacting with stopped Docker containers enables inspecting and debugging, even when the container is not actively running.

    # list of all stopped containers
    docker ps -a
    # Commit the stopped image
    docker commit <stopped_container_id> <new_image_name>
    # Create a new container from the "broken" image
    docker run -it --rm --entrypoint sh <new_image_name>

Pushing image to registry

  • Push/Pull Image to/from local registry
    First setup a local registry
    docker run -d -p 5000:5000 --restart always --name registry registry:2
    docker tag your_docker_image localhost:5000/<image_name>
    docker push localhost:5000/<image_name>
    docker pull localhost:5000/<image_name>
  • Push/Pull Image to/from Docker Hub
    docker tag local_image:tagname username/repository:tagname
    docker push username/repository:tagname
    docker pull username/repository:tagname

Docker Compose

A Docker Compose simplifies the management and orchestration of multiple Docker containers that need to interact with each other. For example, when setting up Kafka locally using a normal Dockerfile approach, you would typically need to run multiple containers for Kafka, ZooKeeper, and possibly other components like Kafdrop. You would have to manage the individual containers separately, ensuring they are started in the correct order, exposing the necessary ports, and configuring their interactions.
However, with Docker Compose, you can define and manage all these containers and their dependencies using a single YAML file, known as the Docker Compose file. This file allows you to specify the services (containers) you need, their configurations, networking requirements, volumes, and any other necessary settings. Given below is a simple docker-compose file for setting up kafka, zookeeper, kafdrop locally.

version: "2"
services:
  kafdrop:
    image: obsidiandynamics/kafdrop
    restart: "no"
    ports:
      - "9000:9000"
    environment:
      KAFKA_BROKERCONNECT: "kafka:29092"
      JVM_OPTS: "-Xms16M -Xmx48M -Xss180K -XX:-TieredCompilation -XX:+UseStringDeduplication -noverify"
    depends_on:
      - "kafka"
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: "0"
    ports:
      - 32181:2181
  kafka:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper
    ports:
      - 9092:9092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: "INTERNAL://:29092,EXTERNAL://:9092"
      KAFKA_ADVERTISED_LISTENERS: "INTERNAL://kafka:29092,EXTERNAL://localhost:9092"
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT"
      KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
      KAFKA_ZOOKEEPER_SESSION_TIMEOUT: "6000"
      KAFKA_RESTART_ATTEMPTS: "10"
      KAFKA_RESTART_DELAY: "5"
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

Command to start the containers defined in a Docker Compose yaml file :
docker compose -f <yaml_file_path> up