Understanding Docker
What is Docker?
Docker is an open-source platform designed for developing, shipping, and running applications. It enables users to separate infrastructure components from applications, creating smaller granular units called containers, which accelerates software delivery speed.
While Docker containers share similarities with virtual machines, they operate on different principles. Containers virtualize the operating system layer, whereas virtual machines virtualize hardware. This makes containers more portable and efficient in server utilization. Containers serve as standardized software units that can ignore infrastructure differences, allowing deployment any where. Docker also provides robust industry-standard isolation.
Docker leverages Linux kernel resource isolation mechanisms like cgroups and namespaces to create independent containers. This operates within a single Linux entity, avoiding the overhead of starting a virtual machine. Linux kernel namespace support completely isolates application work environments, including process trees, networks, user IDs, and mounted file systems. The kernel's cgroup provides resource isolation for CPU, memory, block I/O, and network.
Why Use Docker?
- Efficient Resource Utilization: Containers avoid hardware virtualization and full OS overhead, making Docker more resource-efficient than traditional VMs in execution speed, memory usage, and file storage.
- Rapid Startup Times: Traditional VMs take minutes to start, while Docker containers can start in seconds or milliseconds since they run directly on the host kernel.
- Consistent Environments: Docker images provide complete runtime environments (except the kernel), eliminating the classic "it works on my machine" problems acros development, testing, and production.
- Continuous Delivery: Developers can create custom images using Dockerfiles, integrate with CI systems for testing, while ops teams can deploy directly in production or use automated deployment pipelines.
- Easy Migration: Docker ensures consistent execution environments across physical machines, VMs, clouds, and laptops, simplifying application migration.
- Simplified Maintenance: Layered storage and image technology make application reuse easier, maintenance simpler, and extension straightforward. Official high-quality images reduce creation costs.
Docker Installation
Linux Systems
For fresh installations, execute as root:
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
If upgrading from older installations, first remove Docker:
sudo apt-get purge docker docker-engine docker.io containerd runc
Alternative installation using package manager (Ubuntu example):
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Verify installation:
docker --version
docker info
To avoid using sudo with Docker commands:
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
Start and enable Docker service:
sudo systemctl start docker
sudo systemctl enable docker
Windows Systems
Download Docker Desktop from the official website and run the installer. The application provides a graphical interface for managing containers, images, and settings.
Working with Docker Images
Image Concepts
Docker images are read-only templates containing filesystems. Images are binary files typically created by inheriting from base images and adding customizations. For example, you can extend an Ubuntu image by adding Apache server to create a custom web server image.
Pulling Images
Download images from registries:
docker pull [REGISTRY_HOST/][USERNAME/]NAME[:TAG]
docker pull nginx:alpine
docker pull myregistry.local:5000/test/custom-image
Managing Images
List local images:
docker image ls
docker images
Get detailed image information:
docker image inspect nginx:alpine
docker inspect -f '{{.Architecture}}' nginx
Search for images in registries:
docker search --filter=stars=100 nginx
docker search --automated mysql
Remove images:
docker image rm nginx:alpine
docker rmi image_id
Creating Images
Methods include:
- From existing containers
- From local templates
- Using Dockerfiles (recommended)
Example from container:
docker run -it ubuntu:latest /bin/bash
# Make modifications inside container
apt-get update && apt-get install -y curl
exit
docker commit -a "Author Name" -m "Added curl" container_id myimage:tag
Import from template:
cat ubuntu-20.04-minimal.tar.gz | docker import - ubuntu:20.04-minimal
Image Distribution
Save images to files:
docker save -o myimage.tar myimage:tag
Load from files:
docker load -i myimage.tar
docker load < myimage.tar
Container Management
Container Lifecycle
Containers are runnable instances of images. They include an additional writable layer. The relationship between images and containers is like classes and objects in OOP.
Creating Containers
Create without starting:
docker create -it --name mycontainer ubuntu:latest
Create and start immediately:
docker run -d --name webserver nginx:alpine
docker run -it --rm ubuntu:latest /bin/bash
When running containers, Docker performs these steps:
- Checks for local image, downloads if needed
- Creates container with writable layer
- Configures networking
- Assigns IP address
- Executes the specified command
Container Operations
Stop containers:
docker stop webserver
docker kill --signal=SIGTERM webserver
Start/restart containers:
docker start mycontainer
docker restart webserver
Access running containers:
docker attach container_name
docker exec -it container_id /bin/bash
docker exec -d container_id background_command
Remove containers:
docker rm container_name
docker rm -f running_container
docker container prune # Remove all stopped containers
Container Export/Import
Export container filesystem:
docker export container_id > container_backup.tar
docker export -o backup.tar container_name
Import as new image:
docker import container_backup.tar newimage:tag
cat container_backup.tar | docker import - newimage:latest
Docker Registries and Repositories
Registry Concepts
Repositories store images, while registries host repositories. Docker Hub is the default public registry. Private registries can be self-hosted or use cloud services.
Login to registries:
docker login registry.example.com
docker login -u username -p password private-registry.io
Push images to registries:
docker tag local-image:tag username/repository:tag
docker push username/repository:tag
Pull from private registries:
docker pull private-registry.io/namespace/image:tag
Setting Up Vulhub for Security Testing
Prerequisites
Install Docker Compose:
pip install docker-compose
# Or
sudo apt-get install docker-compose
Verify installation:
docker-compose --version
Deploying Vulnerable Environments
Clone Vulhub repsoitory:
git clone https://github.com/vulhub/vulhub.git
cd vulhub
Navigate to desired vulnerability directory:
cd flask/ssti
cd struts2/s2-016
cd wordpress/pwnscriptum
Build and start the environment:
docker-compose build # Optional, up command includes this
docker-compose up -d
Accessing Test Environments
Check container status and IP:
docker ps
docker inspect container_id | grep IPAddress
docker-compose exec container ip addr
Access the vulnerable application:
curl http://container_ip:port
# Or in browser
http://localhost:port
Cleanup after testing:
docker-compose down -v
docker system prune -a