Docker Basics
Welcome to the foundational layer of Docker! After installing Docker on your VPS (we’ll cover that in the Installing Docker chapter), you’ll need to understand these core concepts to build and manage applications effectively. Think of them as the building blocks that transform your VPS into a flexible, production-ready environment. Let’s break them down step by step.
Understanding Docker Images
An image is a read-only template that defines how a container should be constructed. It’s like a “blueprint” containing all the code, dependencies, and configurations needed to run an application. Images are built from a Dockerfile (a text file with instructions) or pulled from a registry (like Docker Hub).
Here’s how you interact with images:
<code class="language-bash"># List all available images (shows your local images) <p>docker images</p> <h1>Pull a prebuilt Ubuntu image (common for demos)</h1> <p>docker pull ubuntu:latest</code>
Why images matter:
Images are lightweight and portable. When you pull ubuntu:latest, you get a standardized environment that works across any VPS—no manual configuration needed. This consistency is why Docker is so powerful for production deployments.
Real-world example: A web server
Imagine you need a web server. Instead of installing Apache manually on your VPS, you pull an image:
<code class="language-bash">docker pull apache:2.4</code>
This gives you a ready-to-run web server in minutes—no server config, no dependencies.
Working with Containers
A container is a running instance of an image. It’s an isolated environment where your application executes. Containers share the host OS kernel but run in their own isolated space—making them fast and efficient.
Key container operations:
<code class="language-bash"># Run a container from the Ubuntu image (interactive shell) <p>docker run -it ubuntu:latest bash</p> <h1>Run a container in the background (for a web server)</h1> <p>docker run -d -p 8080:80 nginx</code>
Why containers matter:
Containers are ephemeral but powerful. They let you run multiple applications on one VPS without conflicts. For example, you could run a database container and a web server container on the same VPS—each with its own resources and network isolation.
Real-world example: A production web app
After pulling a Python app image:
<code class="language-bash">docker run -d -p 5000:5000 my-app:latest</code>
Your app runs in a container, accessible at http://your-vps-ip:5000. If the container crashes, it restarts automatically (via Docker’s built-in resilience).
Managing Volumes
Volumes are persistent storage areas that live outside the container lifecycle. Unlike container filesystems (which vanish when the container stops), volumes keep data safe even after restarts. They’re crucial for production apps that need to retain data (like databases).
How to use volumes:
<code class="language-bash"># Create a new volume (named 'app-data') <p>docker volume create app-data</p> <h1>Run a container using the volume (maps volume to container path)</h1> <p>docker run -v app-data:/app/data -it ubuntu:latest bash</code>
Why volumes matter:
Without volumes, your app data would be lost when the container restarts. Volumes solve this by decoupling data from containers—perfect for databases, logs, or user uploads. In production, you’ll often use volumes to back up data without downtime.
Real-world example: A database with persistence
For a PostgreSQL database:
<code class="language-bash">docker volume create pg-data <p>docker run -v pg-data:/var/lib/postgresql/data -d postgres:latest</code>
Now, your database data persists even if the container restarts—critical for real-world apps.
Networking in Docker
Docker’s networking enables containers to communicate with each other and the outside world. By default, containers run in a private network, but you can create custom networks to control traffic flow.
Key networking operations:
<code class="language-bash"># Create a custom network (for container communication) <p>docker network create my-app-net</p> <h1>Run two containers on the same network</h1> <p>docker run --network my-app-net -d --name web-server nginx</p> <p>docker run --network my-app-net -d --name db postgres:latest</code>
Why networking matters:
In production, you’ll need to isolate services (e.g., web servers from databases) and control traffic. Docker networks let you define rules for how containers talk—like allowing only specific ports between services.
Real-world example: Microservices communication
In a microservice architecture:
<code class="language-bash"># Container A (web service) <p>docker run --network my-app-net -d --name web-service -p 8080:80 nginx</p> <h1>Container B (API service)</h1> <p>docker run --network my-app-net -d --name api-service -p 5000:5000 my-api:latest</code>
Now, web-service can communicate with api-service without exposing ports to the internet—secure and scalable.
| Concept | What It Is | Key Use Case |
|---|---|---|
| Image | Read-only template for a container | Standardized environments (e.g., nginx:alpine) |
| Container | Running instance of an image | Application execution (e.g., web server) |
| Volume | Persistent storage outside containers | Data persistence (e.g., databases) |
| Network | Isolated communication layer for containers | Service-to-service communication |
Summary
You’ve now mastered Docker’s four pillars:
- Images provide consistent, portable application templates.
- Containers run applications in isolated, resource-efficient environments.
- Volumes ensure critical data persists across container restarts.
- Networks enable secure, controlled communication between services.
These concepts form the backbone of production-grade Docker deployments on VPS hosts. In the next section, we’ll dive into Advanced Docker Configuration—where you’ll learn to optimize these components for high availability and scalability. Keep building! 🐳