Docker has revolutionized how developers build, ship, and run applications. Instead of worrying about server configurations, dependencies, and "it works on my machine" problems, Docker packages everything your application needs into a portable container that runs identically everywhere.
This guide teaches you Docker from zero, with practical examples you can run on your VPS today.
What is Docker?
Think of Docker containers like shipping containers for software. Just as a shipping container can hold any goods and be transported on any ship, truck, or train, a Docker container holds your application and all its dependencies, and runs on any server with Docker installed.
Key concepts in simple terms:
- Image - A blueprint/template for your application (like a recipe)
- Container - A running instance of an image (like a cooked meal from the recipe)
- Dockerfile - Instructions to build an image (the recipe itself)
- Docker Compose - A tool to run multiple containers together (a full menu)
- Volume - Persistent storage for containers (the pantry)
Docker vs Virtual Machines
| Feature | Docker Containers | Virtual Machines |
|---|---|---|
| Startup Time | Seconds | Minutes |
| Size | MBs (typically 50-500 MB) | GBs (typically 5-20 GB) |
| Performance | Near-native | Overhead from hypervisor |
| Isolation | Process-level | Full OS-level |
| OS Support | Shares host kernel | Full OS per VM |
| Resource Usage | Minimal | Heavy (full OS per VM) |
| Density | 100s per host | 10s per host |
| Use Case | Microservices, apps | Full OS isolation needed |
Installing Docker on Your VPS
Install Docker on Ubuntu 22.04/24.04:
# Update package index
sudo apt update
# Install prerequisites
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
# Add your user to docker group (run without sudo)
sudo usermod -aG docker $USER
# Verify installation
docker --version
docker compose version
sudo.
Docker Core Concepts
Images
Images are read-only templates. They're built in layers - each instruction in a Dockerfile creates a new layer. Popular images are available on Docker Hub (hub.docker.com).
# Pull an image from Docker Hub
docker pull nginx
docker pull node:20-alpine
docker pull postgres:16
# List downloaded images
docker images
# Remove an image
docker rmi nginx
Containers
Containers are running instances of images. You can start, stop, and delete containers without affecting the image.
Volumes
By default, data inside a container is lost when the container is removed. Volumes persist data outside the container lifecycle.
# Create a named volume
docker volume create mydata
# List volumes
docker volume ls
# Use a volume when running a container
docker run -v mydata:/data nginx
Networks
Docker creates isolated networks so containers can communicate with each other securely.
# Create a network
docker network create mynetwork
# Run containers on the same network
docker run --network mynetwork --name web nginx
docker run --network mynetwork --name db postgres:16
Essential Docker Commands
| Command | Description | Example |
|---|---|---|
docker run | Create and start container | docker run -d -p 80:80 nginx |
docker ps | List running containers | docker ps -a |
docker stop | Stop a container | docker stop my-container |
docker start | Start a stopped container | docker start my-container |
docker rm | Remove a container | docker rm my-container |
docker logs | View container logs | docker logs -f my-container |
docker exec | Run command in container | docker exec -it my-container bash |
docker build | Build image from Dockerfile | docker build -t myapp . |
docker images | List images | docker images |
docker pull | Download an image | docker pull redis:7 |
docker compose up | Start all services | docker compose up -d |
docker compose down | Stop all services | docker compose down |
Your First Docker Container
# Run Nginx web server
docker run -d --name my-website -p 80:80 nginx
# Explanation:
# -d = Run in background (detached)
# --name = Give the container a name
# -p 80:80 = Map port 80 on host to port 80 in container
# nginx = The image to use
# Check it's running
docker ps
# Visit http://your_server_ip - you'll see the Nginx welcome page!
# View logs
docker logs my-website
# Stop the container
docker stop my-website
# Remove the container
docker rm my-website
Serve Your Own Website
# Create a simple website
mkdir ~/my-site
echo '<h1>Hello from Docker!</h1>' > ~/my-site/index.html
# Run Nginx with your content
docker run -d --name my-website \
-p 80:80 \
-v ~/my-site:/usr/share/nginx/html:ro \
nginx
# Now http://your_server_ip shows YOUR page!
Dockerfiles: Building Custom Images
A Dockerfile contains instructions to build your own Docker image.
Example: Node.js Application
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
# Build the image
docker build -t my-node-app .
# Run it
docker run -d -p 3000:3000 my-node-app
Dockerfile Best Practices
- Use Alpine images -
node:20-alpineis 50 MB vsnode:20at 1 GB - Multi-stage builds - Separate build and runtime stages
- Copy package files first - Leverage Docker layer caching
- Use .dockerignore - Exclude node_modules, .git, etc.
- Don't run as root - Add
USER nodefor security
Docker Compose: Multi-Container Applications
Docker Compose lets you define and run multi-container applications with a single YAML file.
Example: Node.js App with MongoDB and Redis
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- MONGO_URL=mongodb://mongo:27017/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- mongo
- redis
restart: unless-stopped
mongo:
image: mongo:7
volumes:
- mongo-data:/data/db
restart: unless-stopped
redis:
image: redis:7-alpine
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
restart: unless-stopped
volumes:
mongo-data:
# Start all services
docker compose up -d
# View logs for all services
docker compose logs -f
# Stop all services
docker compose down
# Rebuild and restart
docker compose up -d --build
Docker Best Practices for VPS
Clean Up Unused Resources
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune -a
# Remove unused volumes
docker volume prune
# Remove everything unused (nuclear option)
docker system prune -a --volumes
# Check disk usage
docker system df
Resource Limits
# Limit container memory and CPU
docker run -d \
--memory="512m" \
--cpus="1.0" \
--name my-app \
my-node-app
# In docker-compose.yml:
# services:
# app:
# deploy:
# resources:
# limits:
# cpus: '1.0'
# memory: 512M
Security Best Practices
- Never run containers as root - Use
USERinstruction in Dockerfile - Scan images for vulnerabilities - Use
docker scoutor Trivy - Keep images updated - Regularly pull latest base images
- Use read-only filesystem -
docker run --read-only - Don't store secrets in images - Use environment variables or Docker secrets
/var/run/docker.sock) to containers unless absolutely necessary. This gives the container root access to your entire host system. For more security tips, read our VPS security guide.
Troubleshooting Docker Issues
Container Won't Start
# Check container logs
docker logs my-container
# Inspect container details
docker inspect my-container
# Check if port is already in use
ss -tulnp | grep :80
Out of Disk Space
# Check Docker disk usage
docker system df
# Clean up everything
docker system prune -a
# Check host disk space
df -h
Container Can't Connect to Network
# List networks
docker network ls
# Inspect network
docker network inspect bridge
# Make sure containers are on the same network
docker network connect mynetwork my-container
Frequently Asked Questions
How much RAM does Docker need on a VPS?
Docker itself uses about 100 MB. The total depends on your containers. For a typical web application with a database, 2 GB RAM is a good starting point. Check our VPS provider comparison for affordable options.
Is Docker free to use?
Yes! Docker Engine (the runtime) is free and open-source. Docker Desktop (for Mac/Windows) has a paid subscription for large companies, but on a Linux VPS, everything is free.
Should I use Docker for a simple website?
For a simple static site, Docker is overkill. But for applications with databases, caching layers, or complex dependencies, Docker makes deployment and maintenance much easier.
What's the difference between Docker and Kubernetes?
Docker runs containers on a single machine. Kubernetes orchestrates containers across multiple machines for high availability and scaling. Start with Docker; move to Kubernetes when you need multiple servers.
How do I update a Docker container?
Pull the latest image with docker pull image:tag, then recreate the container. With Docker Compose: docker compose pull && docker compose up -d. Your data persists in volumes.
Can I use Docker with VPS Commander?
Yes! VPS Commander works with any VPS and lets you manage files, view logs, and execute Docker commands through a visual web interface without SSH.
Conclusion
Docker simplifies application deployment by packaging everything into portable containers. With the knowledge from this guide, you can now install Docker on your VPS, build custom images with Dockerfiles, and orchestrate multi-container applications with Docker Compose.
Start simple - containerize one application, get comfortable with the commands, then expand to multi-container setups. The time invested in learning Docker pays off enormously in easier deployments, consistent environments, and faster scaling.