Docker Life cycle - Intro

Docker Workflow
Docker follows a predictable lifecycle. Each step helps move an application from development to execution in a consistent manner.
1. Create
Build the Docker image using a Dockerfile.
Packages code, dependencies, runtime, and configs into an immutable artifact.
docker build -t myapp:v1 .
2. Store
Push the built image to a container registry such as Docker Hub, GCR, ECR or a private registry.
docker push myapp:v1
Central storage ensures consistent versions across environments.
example : hub.docker.com
3. Pull / Download
Retrieve the image from the registry before running it.
docker pull myapp:v1
Ensures the executed container matches the stored version.
4. Run
Start the container using the image.
Runs your application in an isolated and lightweight environment.
docker run myapp:v1
5. Destroy
Stop and remove the container once the job completes or a new version is deployed.
docker rm -f <container_id>
docker rmi
Docker Components
Understanding Docker requires clarity on four core building blocks. These components describe how applications are packaged, stored, shared and run in isolated environments.
1. Image
An image is a compressed, read-only template. It contains everything needed to create a container including base OS filesystem layers, dependencies, configuration and the application code.
It acts as the blueprint for the container.
You never “run” an image directly, you instantiate it into a container.
2. Container
A container is a running instance of an image.
It provides isolation using Linux namespaces and cgroups.
Containers remain lightweight because they share the host kernel.
Containers are ephemeral. You can start, stop or destroy them without affecting the underlying image.
Example command
docker run -it ubuntu:latest bash
3. Registry
A registry is a central location where Docker images are pushed and retrieved.
It can be public (Docker Hub) or private (GCR, ECR, Harbor).
Registries enable consistent distribution across teams and environments.
Push and pull examples
docker push myapp:v1
docker pull myapp:v1
4. Repository
A repository groups all versions (tags) of a specific image inside a registry.
For example:
ubuntu:18.04, ubuntu:20.04, ubuntu:22.04 are tags under the ubuntu repository.
This helps maintain structured versioning and rollback capability.
Mermaid Diagram: Docker Components Overview
This diagram represents the lifecycle:
Developers build an image
The image is stored as versions in a repository
The repository lives inside a registry
When needed, the image is pulled and converted into a container
Summary Table
| Component | Purpose | Example |
| Image | Blueprint to create containers | ubuntu:20.04 |
| Container | Runtime instance of an image | Running web server |
| Repository | Stores image versions | ubuntu, nginx |
| Registry | Remote image store | Docker Hub, ECR |
Docker Images
A Docker image is a blueprint that defines everything required to create a container.
A container is simply the running instance of that image.
Images are read-only templates that bundle:
Base operating system layers
Application code
Dependencies and libraries
Configuration and metadata
Entrypoint or commands to run the application
Images ensure applications behave the same across all environments.
How Images Are Created
Images are defined using a Dockerfile, which contains step-by-step instructions such as:
Selecting a base image
Setting environment variables
Configuring the working directory
Copying application source code
Installing dependencies
Exposing ports
Defining the entrypoint or command
Example Build Command
docker build --tag django.nv .
This command:
Reads the Dockerfile in the current directory
Builds an image
Tags it as
django.nv
Core Elements in a Dockerfile
Base Images Starting point for your application such as
ubuntu,python:3.11,alpine.Port Binding Declares which ports the container exposes.
Entrypoint Defines the main executable that always runs.
Command (CMD) Default arguments supplied to the entrypoint.
Volumes Declares persistent or shared directories.
User Sets the user inside the container for security.
Working Directory Defines where commands will run inside the container.
Environment Variables Supplies runtime configuration.
Copy Instructions Moves application code or files into the image.
Sample Dockerfile
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Copy requirement file
COPY requirements.txt .
# Install dependencies
RUN pip install -r requirements.txt
# Copy application
COPY . .
# Set environment variables
ENV APP_ENV=production
# Expose app port
EXPOSE 8000
# Default command
CMD ["python", "app.py"]
Mermaid Diagram: Docker Image Creation Flow
Create Docker image
To create a Docker image named django.nv with version 1.0, you run:
docker build --tag django.nv:1.0 .
Nothing mystical. The command:
docker build tells Docker to create an image.
-tag django.nv:1.0 gives the image a name and version.
. tells Docker to use the Dockerfile in the current directory.
Docker Registry
A registry is a place where you store and retrieve Docker images. Docker supports both public and private registries.
Organizations often maintain private registries on-prem or in cloud environments. AWS, GCP and Azure offer managed registry services.
You must authenticate before you push or pull images from private registries.
$ docker login -u <username> -p <password> docker.domain.com
Login Succeeded
Registry Structure
Registry / Repository / Version
Examples:
docker.io / nmap / latest
docker.io / bandit / 1.0.1
Reference
https://docs.docker.com/registry/
Downloading a Docker Image
Before downloading images from a private registry, authentication is required. Public images can be pulled without login.
If no version is specified during a pull, Docker defaults to using latest.
How Image Naming Works
A fully qualified Docker image reference follows this structure:
Registry / Repository / Version
Examples
docker.io/nmap:latest
docker.io/bandit:1.0.1
Pulling an Image
To download an image from a repository, use the docker pull command.
Example
docker pull registry.domain.com/username/ubuntu:16.04
This pulls the ubuntu:16.04 version from the specified private registry.
Mermaid Diagram: Image Reference Structure
The diagram shows how Docker identifies an image by chaining:
Registry (where the image is stored)
Repository (the image family or name)
Version Tag (specific release of the image)
Key Points
Login is required for private registries.
Omission of the tag defaults to
latest.Pulling retrieves an image and stores it locally for later use.
Docker Repository
A repository organizes and stores multiple versions of a Docker image. It behaves like a namespace similar to a git repository that holds several releases.
If an image tag is not specified, Docker uses latest by default.
To tag an image before pushing it to a registry, use the -t or tag option.
Tag Example
docker tag django.nv:1.0 registry.domain.com/username/django.nv:1.0
Push Example
docker push registry.domain.com/username/django.nv:1.0
Repository Structure
Registry / Repository / Version
Examples:
docker.io / nmap / latest
docker.io / bandit / 1.0.1
A registry stores repositories.
A repository stores all tagged versions of an image.
Example
1 - searching
raj@raj-ubuntu:~$ docker search nmap
NAME DESCRIPTION STARS OFFICIAL
securecodebox/nmap A Docker image containing the NMAP security … 30
demisto/nmap 0
parrotsec/nmap Official Parrot container for nmap 1
instrumentisto/nmap Nmap ("Network Mapper") Docker Image 30
frapsoft/nmap nmap on Alpine Linux (6 MB) 3
uzyexe/nmap nmap container image (size: 14.93MB) 32
networkstatic/nmap Dockerized Nmap Port Scanner on Debian 6
appsmanager/nmap 1
sneakerhax/nmap A Dockerized version of Nmap 0
flibustier/nmap NMAP based on Alpine 2
sammascanner/nmap Nmap Scanner Will run and then save the res… 1
volterraio/nmap 0
bytesizedalex/nmap Alpine Linux image with nmap network scanner. 0
blairy/nmap Single concern container to execute the most… 1
vonahisec/nmap A simple Nmap docker image. 0
n4n0m4c/nmap docker nmap 1
nikhen/nmap This is a docker container including nmap in… 0
cyberwatch/nmap Docker Image with Nmap build from source 4
dockerpinata/nmap 0
k0st/nmap Nmap on minimum, modern and secure Alpine di… 4
functions/nmap 0
tomkukral/nmap 0
whiteadam/nmap Alpine Linux image with nmap, libssl, and ca… 0
nitrogen17/nmap ubuntu 18.04 with nmap 0
linosgian/nmap 0
2- pulling
raj@raj-ubuntu:~$ docker pull uzyexe/nmap
Using default tag: latest
latest: Pulling from uzyexe/nmap
b0dc45cd432d: Pull complete
364328af40b6: Pull complete
9c7abf28af64: Pull complete
635bab23d5f1: Pull complete
054e7786c1b6: Pull complete
5100e35a43b2: Pull complete
d908e559dfdc: Pull complete
aaed4af89abd: Pull complete
Digest: sha256:efd58ad449b98ae71ad1e1690af7e2c940117dd61a66c902da9d894fafa92e52
Status: Downloaded newer image for uzyexe/nmap:latest
docker.io/uzyexe/nmap:latest
3 - run
raj@raj-ubuntu:~$ docker run -t uzyexe/nmap:latest localhost
Starting Nmap 7.80 ( <https://nmap.org> ) at 2025-12-09 15:43 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000090s latency).
Other addresses for localhost (not scanned): ::1
All 1000 scanned ports on localhost (127.0.0.1) are closed
Nmap done: 1 IP address (1 host up) scanned in 0.15 seconds
In the world of Docker:
localhostdoes NOT mean your Ubuntu computer (raj-ubuntu).localhostmeans the container itself.
You asked the container to scan itself. Since uzyexe/nmap is a tiny container with only the scanner installed and no web servers or databases running inside it, it correctly reported that it has no open ports.
How to touch the host computer from container
If you want the container to "break out" and scan your Ubuntu box (raj-ubuntu), you need to attach it to the host's network.
Run this command instead (notice the added flag):
Bash
docker run --network host -t uzyexe/nmap:latest localhost
-network host: This removes the network isolation. Now, when the container says "localhost," it actually refers to your real Ubuntu server.Outcome: You might see port 22 (SSH) open now, since you are SSH'ed into that box.
raj@raj-ubuntu:~$ docker run --network host -t uzyexe/nmap:latest localhost
Starting Nmap 7.80 ( <https://nmap.org> ) at 2025-12-09 15:47 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000014s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
631/tcp open ipp
Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds
Docker Expose
A container can expose ports to the outside world so external systems can communicate with the application running inside it.
You expose ports during runtime using the -p or –publish option.
Syntax
docker run -p HOST_PORT:DOCKER_PORT image-name
Examples
docker run -p 8000:8000 django.nv:1.0
docker run -p 8000:8000 -p 8001:8001 django.nv:1.0
Example Dockerfile
# Python base image
FROM python:2
# Copy startup script
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN ./reset_db.sh
# Expose port 8000 for communication
EXPOSE 8000
# Command executed when container starts
CMD ["/app/runapp.sh"]
EXPOSEis documentation. It does not open the port automatically.docker run -pis what binds a container port to a host port.Multiple ports can be exposed and published as needed.
Docker Mount
A container has its own filesystem. When it stops, that filesystem disappears unless you explicitly mount a folder from the host. Mounts let you:
Save output or logs
Edit files on your host and see the changes instantly inside the container
Treat a folder like a shared directory between host and container
Think of a mount as telling Docker:
“Use this real folder on my machine instead of creating a temporary filesystem.”
docker run -v HOST_DIR:CONTAINER_DIR image-name
Meaning:
| Part | Explanation |
| HOST_DIR | The actual folder on your machine |
| CONTAINER_DIR | Where the container will see that folder |
| -v | The mount instruction |
Example 1: Mount local ./app to /app inside container
docker run -v ./app:/app django.nv:1.0
Inside the container, /app now shows your local ./app contents.
Example 2: Mount current working directory
docker run -v $(pwd):/app django.nv:1.0
Great when you are developing on your host and want the container to use the same files.
Why mount is essential?
Without mount:
The container writes data.
The container exits.
The data is gone.
With mount:
Data is written into your real filesystem.
You can inspect, modify, and reuse it even after the container dies.
clean up
when i checked for the docker process in the system
raj@raj-ubuntu:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4651276a2f11 uzyexe/nmap:latest "nmap localhost" 2 minutes ago Exited (0) 2 minutes ago mystifying_brown
69ea0d81a079 uzyexe/nmap:latest "nmap localhost" 6 minutes ago Exited (0) 6 minutes ago kind_kepler
raj@raj-ubuntu:~$ docker rm 4651276a2f11
4651276a2f11
raj@raj-ubuntu:~$ docker rm 69ea0d81a079
69ea0d81a079
raj@raj-ubuntu:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
The "Pro Tip" for next time
Since Nmap is a "one-off" tool (you run it, get results, and leave), you don't want to manually delete the container every single time.
Use the --rm flag in your run command next time:
Bash
docker run --rm -t uzyexe/nmap scanme.nmap.org
-rm: "Automatically remove this container the moment it finishes."
Now the big question should i need to run the docker pull command again ?
NO. You do not need to pull again.
You removed the Container (the instance), but you kept the Image (the software/installer).
The "App Store" Analogy
Think of the Docker Image like an app on your phone (e.g., WhatsApp). Think of the Docker Container like "Opening WhatsApp to send a message."
docker pull: Downloading WhatsApp from the App Store. (You did this once).docker run: Opening the app.docker rm: Closing the app (swiping it away).
You just "swiped away" the app. You did not uninstall it. If you want to run it again, just type docker run ... and it will start instantly without downloading anything.
here is the proof
raj@raj-ubuntu:~$ docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
uzyexe/nmap:latest 1166ff5a6b0a 18.5MB 0B
Detached Mode
A container can run in detached mode so your terminal stays free for other work.
Use the -d or --detach option when starting a container.
Why detached mode matters
The container runs in the background
Your terminal is not blocked
Useful for servers, APIs or long-running tasks
Commands
docker run -d image-name
Run with a custom name:
docker run --name webserver -d nginx
Stop the detached container:
docker stop webserver





