Docker: A Structured Guide¶
Table of Contents¶
- What is Docker
- Key Features and Benefits
- Problems Docker Solves
- Dependency and Configuration Management
- Portability
- Complexity
- Inefficiency
- Security
- Docker vs. Virtual Machines
- How Docker Revolutionizes Deployment
- Docker Architecture
- Docker Plugins
- Dockerfile
- Install Docker Engine
- Docker CLI Overview
- Docker Essential Commands
- Docker Commands: Pull, Push, and Tag
- docker build
- docker commit
- docker run
- Port Mapping
- docker volume
- docker network
- Monitoring & Debugging
- docker compose
- Multi-Stage Docker Build
- Troubleshooting
- Key Points
- Conclusion
What is Docker¶
Docker is an open-source platform that allows developers to package, deploy, and run applications in lightweight, portable containers. These containers ensure consistent behavior across various environments, eliminating compatibility issues.
Key Features and Benefits¶
- Lightweight: Containers share the host OS kernel, avoiding the overhead of a full operating system per application.
- Portable: Run containers consistently across any environment that supports Docker.
- Efficient: Containers start and stop quickly, improving development and deployment speed.
- Isolated: Each container operates independently, preventing conflicts between applications.
- Secure: Applications run in isolated, secure environments.
- Scalable: Containers can scale easily to meet demand.
- Ease of Use: Simple tools and automation simplify container management.
- Cross-Platform: Compatible with Linux, macOS, and Windows.
- Community Support: A large ecosystem provides tools and resources for developers.
Problems Docker Solves¶
Dependency and Configuration Management¶
What are Dependencies and Configuration?¶
- Dependencies: External libraries, frameworks, runtime environments, or packages required for an application to run. For example:
- Python applications need specific Python versions and libraries like
DjangoorFlask. -
Java applications may require
JDKor specific.jarfiles. -
Configuration: Environment-specific settings, such as:
- Database connection strings.
- API keys and credentials.
- Server-specific configurations (e.g., ports, memory limits).
How Were Dependencies and Configuration Managed Earlier?¶
-
Manual Installation: Developers manually installed dependencies on each system, often leading to version mismatches.
-
Environment Variations: Applications behaved differently across environments due to inconsistencies in configurations and dependencies.
-
Complex Deployment: Teams had to maintain detailed documentation or scripts to replicate the required environment, which was time-consuming and error-prone.
How Docker Solves This Problem¶
- Docker packages the application, its dependencies, and configurations into Docker images:
- Ensures all dependencies are included, avoiding version conflicts.
- Allows environment-specific configurations to be managed using environment variables or configuration files.
- Docker containers provide a consistent runtime environment, eliminating "it works on my machine" issues.
- Developers can focus on coding without worrying about infrastructure setup.
Portability¶
Before Docker: Applications faced compatibility issues due to differences in operating systems, dependencies, and configurations.
With Docker: - Applications and dependencies are packaged into Docker images, ensuring consistent behavior across environments. - Containers eliminate the need to manage infrastructure dependencies manually.
Complexity¶
Before Docker: Running applications with diverse dependencies required complex configurations.
With Docker: Docker simplifies the process by bundling application code, dependencies, and configurations into a single container.
Inefficiency¶
Before Docker: Traditional methods consumed excessive resources due to redundant OS instances and slow startup times.
With Docker: - Containers share the host OS kernel, drastically reducing resource usage. - They start almost instantly, enabling faster workflows and scaling.
Security¶
Before Docker: Shared environments posed risks of application conflicts and vulnerabilities.
With Docker: Containers isolate applications, minimizing risks and ensuring secure execution.
Docker vs. Virtual Machines¶
Virtual Machines¶
- Each VM includes a full OS, leading to:
- High resource usage (CPU, memory, disk space).
- Slow startup times due to OS booting.
- Inefficient resource sharing and management.
Docker Containers¶
- Containers share the host OS kernel, offering:
- Resource Efficiency: No need for a full OS per container, enabling more containers on the same hardware.
- Fast Startup: Containers start in seconds, ideal for scaling.
- Portability: Containers run consistently across environments without dependency issues.
- Cost-Effectiveness: Reduced resource usage lowers infrastructure costs.
How Docker Revolutionizes Deployment¶
- Unified Workflow: Containers simplify transitions between development, testing, and production environments.
- Rapid Scaling: Instant container startup enables responsive scaling during peak demands.
- Streamlined Management: Tools like Docker Compose and Docker Swarm simplify multi-container application management.
Docker Architecture¶
Docker uses a layered architecture to manage containers. The key components include: - Docker Engine: The core component responsible for creating, managing, and running containers. It includes the Docker daemon and the Docker client. - Docker Hub: A cloud-based registry where users can store and share Docker images. - Docker Objects: These are the building blocks of Docker, including images, containers, volumes, networks, and more. - For details, please click here.
Docker Plugins¶
- Docker Plugins are extensions or add-ons that enhance Docker's functionality.
- These tools integrate with the Docker Engine to provide additional capabilities, simplifying workflows and extending Docker's usability.
- Please click here for more information.
Dockerfile¶
-
It is a text file that contains all the commands a user could call on the command line to assemble an image.
-
For details, please click here.
-
Have a look on its Descritives in depth:
- ARG, ENV, EXPOSE
-
Official Dockerfile Reference
Install Docker Engine¶
- Docker Engine can be installed using different methods depending on your requirements. Please follow these steps to install it.
- Official Documentation
Docker CLI Overview¶
- container
- image
- volume
- network
- system: df, events, info, prune
- authentication: login, logout
- plugins: plugin, context, search
- version
- stats
- manifest
Please click here to learn these commands and their flags in depth.
Docker Essential Commands¶
# Lists all available images on the system.
docker images
# Alias for docker images.
docker image ls
# Filters images with the name 'node'.
docker image ls node
# Lists dangling images (unused image layers).
docker images -f "dangling=true"
# Lists running containers.
docker ps
# Lists all container IDs (running and stopped).
docker ps -a -q
# Displays details of both running containers and images.
docker ps/images/container
# Removes a specific container using its ID.
docker rm CONTAINERID
# Removes all stopped containers.
docker rm $(docker ps -aq)
# Removes all images, both tagged and untagged, -f → Force removes them (even if in use by stopped containers)
docker rmi -f $(docker images -aq)
# Another way to remove all stopped containers.
docker ps -aq | xargs docker rm
# Removes a specific volume by its ID.
docker volume rm VOLID
# Removes a specific image forcibly, either by ID or name.
docker rmi IMAGEID/REPOSITORY:v --force
# Cleans up unused images, containers, networks, and volumes to free up disk space.
docker system prune
Docker Commands: Pull, Push, and Tag¶
# Pull a specific image from Docker Hub (e.g., hello-world)
docker image pull hello-world
# Pull all tags of a specific image (e.g., image_name)
# Useful when you want to download all variants of an image
docker pull --all-tags image_name
# Tag an image from an old repository to a new one (e.g., OLDREPOSITORY:v to mibtisam/NEWREPOSITORY:v)
docker tag OLDREPOSITORY:v mibtisam/NEWREPOSITORY:v
# Tag an image by its Image ID (e.g., IMAGE_ID to my-app:1.0)
docker tag IMAGE_ID my-app:1.0
# Push an image to a Docker repository (e.g., mibtisam/NEWREPOSITORY:v)
docker push mibtisam/NEWREPOSITORY:v
docker build¶
The docker build command is used to create Docker images from a Dockerfile and its associated context. The context refers to the directory sent to the Docker daemon containing the Dockerfile and any files required during the build process. The behavior of the docker build command depends on the correct setup of the context and the path to the Dockerfile.
- For details, please click docker build and docker tag
docker build -t IMAGENAME:version /path/to/docker/context
docker build -t img1:sam /files # ERROR Dockerfile1
docker build -t img1:sam . # ERROR Dockerfile1
docker build -t img1:sam /files # EXECUTED Dockerfile
docker build -t img1:sam . # EXECUTED Dockerfile
docker build -t img:sam -f ../../../Dockerfile1 /files # EXECUTED
docker build -t img:sam -f ../../../Dockerfile2 /files # EXECUTED
¶
docker build -t IMAGENAME:version /path/to/docker/context
docker build -t img1:sam /files # ERROR Dockerfile1
docker build -t img1:sam . # ERROR Dockerfile1
docker build -t img1:sam /files # EXECUTED Dockerfile
docker build -t img1:sam . # EXECUTED Dockerfile
docker build -t img:sam -f ../../../Dockerfile1 /files # EXECUTED
docker build -t img:sam -f ../../../Dockerfile2 /files # EXECUTED
docker commit¶
# Commit the container to a new image
docker commit \
-a "Ibtisam" \
-m "Nginx container with custom CMD, ENV, and exposed port" \
-c 'ENTRYPOINT ["nginx", "-g", "daemon off;"]' \
-c 'CMD ["nginx", "-g", "daemon off;"]' \
-c 'ENV APP_ENV=production PORT=8080' \
-c 'WORKDIR /usr/src/app' \
-c 'EXPOSE 8080' \
-c 'USER nginx' \
-c 'LABEL version="1.0" description="Custom Nginx image"' \
-c 'VOLUME ["/data"]' \
<container_id/name> <image>
¶
# Commit the container to a new image
docker commit \
-a "Ibtisam" \
-m "Nginx container with custom CMD, ENV, and exposed port" \
-c 'ENTRYPOINT ["nginx", "-g", "daemon off;"]' \
-c 'CMD ["nginx", "-g", "daemon off;"]' \
-c 'ENV APP_ENV=production PORT=8080' \
-c 'WORKDIR /usr/src/app' \
-c 'EXPOSE 8080' \
-c 'USER nginx' \
-c 'LABEL version="1.0" description="Custom Nginx image"' \
-c 'VOLUME ["/data"]' \
<container_id/name> <image>
docker run¶
The docker run command is used to create and start a container from a specified image. It is often the first step to interact with a containerized application.
Basic Syntax:¶
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- OPTIONS: Various flags to modify container behavior (e.g.,
-d,--name,--entrypoint). - IMAGE: The image to use for creating the container.
- COMMAND: (Optional) The command to run inside the container.
- ARG: (Optional) Arguments for the specified command.
docker container runis equivalent to:docker container create + docker container start + docker container attach
ENTRYPOINT and CMD¶
- Here's how it works:
- ENTRYPOINT defines the
executableto run. -
CMD provides the default
argumentsto the ENTRYPOINT. -
CMDcan be overridden when running the container. ENTRYPOINTcannot be overridden without using the--entrypointflag.-
If you use the
ENTRYPOINTflag, it doesn't automatically replace theCMDunless you specify a new command after the image name. If no command is specified after overridingENTRYPOINT, Docker will use the defaultCMDfrom the Dockerfile. -
For example:
- If you override
ENTRYPOINTtosleep, but you don't provide any argument, Docker will use theCMDargument from the Dockerfile (if defined). -
If you want to override both, you would need to specify both
ENTRYPOINTandCMDexplicitly. -
Override ENTRYPOINT and CMD
docker run --name <container_name> --entrypoint sleep -d alpine infinity - This command sets the entrypoint to sleep and the argument to infinity. This effectively overrides both the ENTRYPOINT and CMD behavior. The infinity argument overrides whatever CMD was originally defined in the Dockerfile (if any).
docker run --name <container_name> --entrypoint <entrypoint_command> nginx 10 - This overrides both the ENTRYPOINT and CMD defined in the Dockerfile. For example, if the Dockerfile defined: - ENTRYPOINT ["sleep"] - CMD ["5"] - Both ENTRYPOINT and CMD are overridden here.
-
Both points clarify that when an argument is provided for
ENTRYPOINT(likeinfinityor10), it overrides theCMDas well. -
Run and remove the container automatically on exit
docker container run --rm -d --name <container_name> REPOSITORY:v - Runs the container in detached mode and removes it automatically after it stops.
- Run with a shell command
docker run -dit --name myfirstcon REPOSITORY:v /bin/sh - Runs the container with the command /bin/sh, allowing interaction with the shell.
- Run with a shell command to echo a message
docker run --name <container_name> alpine sh -c "echo hello" - Runs the container with the sh command and the argument -c "echo hello", which prints "hello" to the console.
- Run with default command
docker run alpine ls -l - Runs the container with the ls -l command. By default, it lists the contents of the /root directory.
- Run with a custom command and arguments
docker run -dit --name myfirstcon REPOSITORY:v uname -a - Runs the container with the command uname and the argument -a to display system information.
- Run with the sleep command
docker run -dit --name myfirstcon alpine sleep 10 - Runs the container with the sleep command and the argument 10, making the container sleep for 10 seconds before stopping.
- Run with custom capabilities
docker run --cap-add MAC_ADMIN ubuntu sleep 3600 - Adds the MAC_ADMIN capability to the container and runs it for 3600 seconds (1 hour).
docker run --cap-drop KILL ubuntu - Drops the KILL capability from the container, restricting its ability to kill other processes.
- Run with specific user
docker run --user=1000 ubuntu sleep 3600 - Runs the container as the user with UID 1000.
- Run with environment variable and bind mount
docker run -it -d --name <container_name> -e PORT=$MY_PORT -p 7600:$MY_PORT --mount type=bind,src=$PWD/src,dst=/app/src node:$MY_ENV - Runs the container interactively with environment variables, a port binding, and a bind mount.
Port Mapping¶
- Run with port mapping (host:container)
docker run -it --name {} -p 8080:80 nginx /bin/sh
- This command maps port 8080 on the host to port 80 inside the container. It allows you to access the container's nginx service on http://<host-ip>:8080.
- The placeholder {} should be replaced with a container name (e.g., web1).
- Run with port 80 mapped successfully
docker run -it --name web1 -p 80:80 nginx
- Here, port 80 on the host is mapped to port 80 inside the container, meaning the nginx service is accessible from http://<host-ip>:80.
- Run with port 80 already mapped (same as host and container)
docker run -it --name web2 -p 80:80 nginx
- This won't work because port 80 is already in use on the host by another container (web1). Docker will generate a container, but the port mapping is not successful.
- Run with port 8080 on host and port 80 inside container (container ID exists)
docker run -it --name web2 -p 8080:80 nginx
- This command fails if a container with the same name (web2) already exists, as container names must be unique. Even if the container runs, the port is not mapped because the container ID already exists.
- Run with port 8080 already allocated on host
docker run -it --name web3 -p 8080:80 nginx
- If port 8080 is already in use on the host (by another container or application), Docker cannot map the port and the container won’t run as expected. The port is already allocated.
- Run with port 8081 mapped successfully
docker run -it --name web4 -p 8081:80 nginx
- In this case, port 8081 on the host is mapped to port 80 inside the container. This command works as expected and maps the port successfully.
- Run with specific IP for port mapping
docker run --rm -it --name nginx1 -d -p 127.0.0.1:80:8081/tcp nginx
- This command maps port 8081 inside the container to port 80 on the local machine's loopback interface (127.0.0.1). The container is accessible only from the host itself (not from other devices on the network).
- The --rm flag ensures the container is removed after it stops.
Port Binding Protocols:¶
-
Docker uses the TCP protocol by default for port mappings. However, you can also specify other protocols like UDP if needed (e.g.,
-p 80:80/udpfor UDP). -
A service using port 5353 for UDP does not block Docker from binding port 5353 for TCP, as the protocols are distinct and separate. Docker can bind to the same port for both protocols without conflicts.
docker volume¶
Docker supports Named & Anonymous Volumes, Bind Mounts, and tmpfs for managing container data. Please follow this link for more details.
# Creates a Docker-managed named volume `my-volume`, stored under `/var/lib/docker/volumes`
docker volume create my-volume
# Displays metadata about the specified volume, such as mount paths and usage.
docker volume inspect my-volume
# Lists all Docker-managed volumes on the host system.
docker volume ls
# Cleans up all unused volumes to free disk space.
docker volume prune
# Deletes the specified volume permanently.
docker volume rm my-volume
## Just create the volume, no mounting
# Create the container and start shell with ananymous volume mounting.
docker run -it --name cont1 -v /Vo1 alpine /bin/sh
# Volume type: volume (docker-managed volume; docker-named volume)
docker run -it --name cont1 --mount type=volume,source=my-volume,target=/Vol alpine /bin/sh
docker run -it --name cont1 --mount source=my-vol,target=/Vol alpine /bin/sh
docker run -it --name cont1 --mount src=my-vol,dst=/Vol alpine
docker run -it --name cont1 -v my-volume:/Vol alpine /bin/sh
# Volume type: bind (mounts host directory)
mkdir /home/ibtisam/dockr/bind # Create a directory on the host system for mounting.
docker run -it --name cont2 -v /HOST/PATH:/CONTAINER/PATH alpine /bin/sh
docker run -it --name cont2 --mount type=bind,source=/../../,destination=/opt/data alpine /bin/sh
# Volume type: tmpfs (in-memory mount)
docker run -d -it --name cont3 --mount type=tmpfs,destination=/app alpine /bin/sh
docker run -d -it --name cont3 --tmpfs /app alpine /bin/sh
## Sharing the volume between containers
# Create a container `lec-18` with volume `/dbdata`, but container will exit immediately.
docker create -v /dbdata --name lec-18 postgres:13-alpine /bin/true
docker run -d -it --name db1 --volumes-from lec-18 postgres:13-alpine /bin/sh
docker run -d -it --name db2 --volumes-from lec-18 postgres:13-alpine /bin/sh
# Sharing a host directory between containers
docker run -it --name cont-v3 -v /home/ibtisam/docker-bind:/opt/data busybox /bin/sh
docker run -it --name cont-v4 -v /home/ibtisam/docker-bind:/opt/data busybox /bin/sh
## Privileged container to container volume mounting
# Create `container2` and share volumes from `container1`.
docker run -it --name container2 --privileged=true --volume-from container1 ubuntu bin/bash
# Mount host directory `/home/ec2-user` to `/rajput` in `container2`.
docker run -it --name container2 -v /home/ec2-user:/ibtisam --privileged=true ubuntu bin/bash
docker network¶
# Creates a custom Docker network named `my-network`
docker network create my-network
# Displays detailed information about the custom network `my-network`, including connected containers
docker network inspect my-network
# Lists all available Docker networks on the host system
docker network ls
# Removes the specified network `my-network` from Docker
docker network rm my-network
# Removes all unused Docker networks to free disk space
docker network prune
# Connects `container1` to the existing `my-network`
docker network connect my-network container1
# Disconnects `container1` from the `my-network`
docker network disconnect my-network container1
Monitoring & Debugging¶
# Executes an interactive bash shell inside `container1`
docker exec -it container1 /bin/sh
# Gracefully starts/stops the running container `container1`
docker start|stop container1
# Forcefully stops the running container `container1`
docker kill container1
# Pauses the execution of `container1`, suspending its processes
docker pause container1
# Resumes the execution of `container1` after it has been paused
docker unpause container1
# Starts `container1` and attaches to its output stream. This is useful for monitoring logs directly.
docker start --attach container1
# Viewing container logs
docker container logs container1
# Streams real-time logs from `container1`, useful for continuous monitoring of its output.
docker logs -f container1
# Inspecting container details and viewing changes made to the container
# Displays detailed information about `container1` such as its configuration, environment variables, and status.
docker inspect container1
# Shows the changes made to `container1`’s filesystem since it was created, such as added or deleted files.
docker diff container1
# Displays the port mappings for `container1`, showing which host ports are forwarded to container ports
docker container port container1
# Search for images from Docker Hub
docker search nginx
# Converts the inspection output of `container1` into a human-readable YAML format and saves it as `container1.yaml`
docker inspect container1 | python3 -c "import sys, yaml, json; yaml.safe_dump(json.load(sys.stdin), sys.stdout, default_flow_style=False)" > container1.yaml
docker compose¶
Docker Compose is a tool that simplifies the management of multi-container Docker applications. It enables users to define and manage containerized applications using a single YAML file.
Please click here.
Multi-Stage Docker Build¶
Multi-stage builds are an efficient way to create optimized Docker images by separating build and runtime environments. This approach helps in:
- Reducing image size – Only necessary files are included in the final image.
- Enhancing security – Removes unnecessary build tools and dependencies.
- Optimizing performance – Lighter images lead to faster deployments.
How It Works?¶
A multi-stage build consists of multiple FROM instructions, where:
- Each stage produces artifacts that the next stage can use.
- The final image contains only the essential runtime components.
Common Approaches¶
1️⃣ Using Different Images for Build and Runtime¶
-
The first stage uses a larger image (e.g.,
golang,maven,node) to compile/build the application. -
The second stage uses a lighter image (e.g.,
alpine,nginx,scratch) to run the application. -
Use case: When the build process requires additional dependencies (compilers, build tools) that aren’t needed at runtime.
-
Example: A Golang app builds in
golang:latestand runs inalpine. - The runtime stage copies only the virtual environment and app files, avoiding unnecessary tools like
pipandvenv.
For more details, please click here.
2️⃣ Using the First Stage as a Base for the Final Image¶
-
The second stage inherits from the first, but removes or adds dependencies based on the environment.
-
Use case: When the same base image is required across different stages, but with different dependencies (e.g., dev tools in one stage, production-ready minimal setup in another).
-
Example: A Node.js app starts with
node:alpine, installs dev dependencies in the first stage, and only keeps prod dependencies in the final stage.
For more details, please click here.
Benefits of Multi-Stage Builds¶
- Lighter images → Faster pull & deploy times.
- Better security → Removes unused dependencies.
- Environment separation → Dev & prod dependencies managed efficiently.
By leveraging multi-stage builds, Docker images stay optimized, secure, and production-ready, ensuring faster deployments and improved performance.
- How to Choose the Right Base Image for Multi-Stage Builds?
- What are Different Ways to Reduce the Image Size?
Troubleshooting¶
Please read a complete documentation about troubleshooting here.
Key Points¶
-
Use
-itwithdocker run
Always use the-itflags when running a container if you plan to enter the container later usingdocker exec. Without the-itflags, the container will not start in interactive mode, and you won't be able to enter it usingdocker exec. For better access, it's recommended to also add/bin/shas the default shell. -
Running Containers with
-itand-dit
When running a container withdocker run -itordocker run -dit,/bin/shis not mandatory. The container defaults to the/rootdirectory if not specified. -
Using
docker exec
The-itflags are mandatory when usingdocker execif you intend to enter the container. You also need to specify the path to the shell, such as/bin/shor/bin/bash.
However, the path to shell isn't mandatory all the times, like : docker exec {container ID} ls
-
To be in
docker ps
The-itflags are not required to list containers usingdocker ps. You can usedocker startanddocker execto start and interact with a container. -
Stopping and Removing Containers
Use the commandsdocker killordocker stopto stop a container. To remove a container or image, usedocker rmordocker rmi, respectively. -
Starting a Container After Exiting
Once you exit a running container, you need to start it again before usingdocker execto execute commands inside the container. -
Difference between
docker startanddocker exec
docker startanddocker execdiffer fromdocker run. When usingdocker start/exec, the container will not stop unless explicitly instructed to do so. This is different fromdocker run, where the container exits after the command finishes. -
Behavior of
docker runvs.docker start/execwithexit
When usingdocker run, the container exits immediately after running the command (e.g.,exit). However, when usingdocker startordocker exec, the container does not exit until it is explicitly stopped. -
Entering a Container
To enter a container, add the-itflags todocker run. Alternatively, you can add the--attachflag when starting the container to print its output. -
Container ID in Commands
docker rundoes not require a container ID, but commands likedocker exec,docker start,docker stop,docker kill,docker commit,docker inspect, anddocker logsall require a container ID. -
Docker Run vs Docker Build
docker rundoes not require a path to an image, butdocker buildrequires a path to the Dockerfile or the directory where it resides. -
Starting Containers and Output
docker start {containerID}will start the container but will not display any output. To display the container’s output, you need to use the--attachflag withdocker start, like this:docker start --attach {containerID}. -
Re-running Containers
To run the same container, usedocker start --attach {containerID}directly instead of usingdocker exec. -
Using
docker commit
Every time you usedocker commit, a new image ID is generated, regardless of whether changes were made to the container. -
Image Layers in Docker Build
Docker image layers are read-only, and the number of layers corresponds to the number of instructions (lines) in the Dockerfile. -
Error Handling During Build
If an error occurs at any layer during the build process, Docker will stop building further layers and will create an image with the tagnone. -
Dangling Images
A dangling image is an image that does not have an image name or tag but still has an allocated image ID. -
Dangling Image with No Tag
A dangling image has no repository or tag assigned to it but still has an image ID allocated to it. -
Alpine Image Example
When runningdocker images alpine, it will show the Alpine image. However, after runningdocker buildwith theRUN alpinecommand, runningdocker imageswill not show the Alpine image because it was built without tagging. -
Image Name Case Sensitivity
The image name should always be in lowercase. Docker will enforce this naming convention. -
Listing Files with
ls -l
You can rundocker run alpine ls -lto list files in the container. Thels -lcommand will print the output after exiting the container. -
Docker Socket File (
/var/run/docker.sock)
The/var/run/docker.sockfile connects the Docker client with the Docker daemon. If the Docker daemon is stopped, runningdocker ps -awill not show any containers. -
Docker Build Requires a Dockerfile Path
The path to theDockerfileis mandatory when usingdocker build. -
Running Commands in Containers
To run commands in a container, you can use the syntaxdocker run <ls -l> <bin/sh> <bin/ash> <echo “this is ibtisam”>. -
Image ID Changes or Remains the Same
The Image ID remains the same when you delete, tag, or push an image. However, the Image ID will change if there are changes in theDockerfileor if you commit a container, even if no changes were made inside it. -
Creating Images
Image IDs are created when you use commands likedocker build,docker pull, ordocker commit. -
Using Volumes with Containers
You can use the same volume for multiple containers by specifying--name cont1 -v /VOL alpineand--name cont2 -v /VOL alpine. However, each container will have a unique volume ID, so data cannot be shared between them unless you use a bind mount. -
Sharing Data Between Containers
In Docker volumes, each container has a unique volume ID, so the data is not shared between containers. However, in Docker bind mounts, data is shared because there is no volume ID assigned to bind mounts. -
Running a Simple HTTP Server
To run a simple HTTP server usingdocker run, you can use the following command:
docker run -d --rm -p 8080:8080 --name webserver busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'smallest http server'; } | nc -l -p 8080; done". -
Checking Running Containers
You can list all containers (including stopped ones) usingdocker ps -a, or check the port of a specific container withdocker port {CONTAINERID}. -
Checking Open Ports on Host
You can check which ports are open on the host usingnetstat -tuln | grep 8080orss -tuln | grep 8080. -
Accessing a Running Service
You can access the service running on port 8080 by visitinghttp://localhost:8080orhttp://192.168.100.107:8080/. -
Running Nginx Container
You can run an Nginx container with the command:
docker run -dit -p 8080:80 --name myser nginx. However, this may not work as expected if the port is already allocated.
Conclusion¶
Docker provides a lightweight, efficient, and secure alternative to traditional virtual machines. By addressing critical issues like dependency management, configuration consistency, portability, complexity, inefficiency, and security, Docker has become an essential tool for modern software development and deployment. Its ability to maximize resource utilization and scalability makes it indispensable for organizations aiming for agility and cost-efficiency.