Introduction: Why Docker?
Have you ever said “but it works on my machine” only to discover your application crashes when deployed elsewhere? Docker solves this problem by packaging your application and all its dependencies into a standardized unit called a container. Think of containers as lightweight, portable, self-sufficient boxes that can run anywhere Docker is installed.
What You’ll Learn
In this guide, you’ll discover how to:
- Set up Docker on your system
- Understand Docker fundamentals
- Launch your first containers
- Host websites, databases, and more
- Connect services together
- Create development environments
- Save time with pre-built solutions
Let’s dive in!
Getting Started with Docker
Installation
First things first: you need Docker on your system.
For Windows/Mac:
- Download Docker Desktop from docker.com
- Run the installer and follow the prompts
- Start Docker Desktop
For Linux:
# Update package info
sudo apt update
# Install prerequisites
sudo apt install apt-transport-https ca-certificates curl software-properties-common
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Add the Docker repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Update package database
sudo apt update
# Install Docker
sudo apt install docker-ce
# Start Docker
sudo systemctl start docker
# Enable Docker to start on boot
sudo systemctl enable docker
Verify your installation by running:
docker --version
docker run hello-world
Docker Basics
Let’s understand some key Docker terminology:
- Image: A read-only template with instructions for creating a Docker container
- Container: A runnable instance of an image
- Dockerfile: A text file with commands to build an image
- Docker Hub: A repository of Docker images (like GitHub for Docker)
- Volume: A way to persist data generated by and used by Docker containers
- Network: How containers communicate with each other
Your First Project: Hosting a Website
Let’s start with something simple: hosting a static website using Nginx.
Option 1: Using an Official Image
# Create a directory for your website
mkdir my-website
cd my-website
# Create a simple index.html file
echo "<html><body><h1>My Docker Website</h1><p>It works!</p></body></html>" > index.html
# Run an Nginx container, mapping your directory to the container's web root
docker run -d -p 8080:80 -v $(pwd):/usr/share/nginx/html --name my-website nginx
Visit http://localhost:8080 in your browser to see your website!
Option 2: Creating Your Own Image
Create a file named Dockerfile
:
DockerfileCopyFROM nginx:latest
COPY . /usr/share/nginx/html
Build and run your custom image:
docker build -t my-website-image .
docker run -d -p 8080:80 --name my-website my-website-image
Hosting a Database
Next, let’s set up a MySQL database:
# Create a directory for database data
mkdir mysql-data
# Run a MySQL container
docker run -d \
--name my-mysql \
-p 3306:3306 \
-v $(pwd)/mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mysecretpassword \
-e MYSQL_DATABASE=mydatabase \
mysql:8.0
You now have a MySQL database running on port 3306!
Setting Up phpMyAdmin for Database Management
Let’s add phpMyAdmin to manage your MySQL database:
docker run -d \
--name phpmyadmin \
-p 8081:80 \
-e PMA_HOST=my-mysql \
--link my-mysql:db \
phpmyadmin/phpmyadmin
Access phpMyAdmin at http://localhost:8081 and log in with username root
and password mysecretpassword
.
Create a Full Web Stack: WordPress Example
Want to run WordPress? It’s simple with Docker:
# Create a network for WordPress and MySQL to communicate
docker network create wordpress-network
# Run MySQL for WordPress
docker run -d \
--name wordpress-db \
--network wordpress-network \
-v wordpress-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mysecretpassword \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=wordpress \
mysql:5.7
# Run WordPress
docker run -d \
--name wordpress \
--network wordpress-network \
-p 8080:80 \
-e WORDPRESS_DB_HOST=wordpress-db \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress \
-e WORDPRESS_DB_NAME=wordpress \
wordpress
Visit http://localhost:8080 to set up your WordPress site!
Remote Desktop in Docker
Need a GUI environment? You can run a Remote Desktop inside Docker:
docker run -d \
--name remote-desktop \
-p 3389:3389 \
-e USER=myuser \
-e PASSWORD=mypassword \
--shm-size 1g \
rattydave/docker-ubuntu-xrdp-mate-custom:latest
Connect to your remote desktop using any RDP client (like Microsoft Remote Desktop) at localhost:3389.
Development Environments
VS Code Remote Development
The VS Code Remote Development extension allows you to use a container as a development environment:
- Install VS Code and the “Remote – Containers” extension
- Create a
.devcontainer
folder in your project - Add a
devcontainer.json
file:
jsonCopy{
"name": "Node.js Development",
"image": "node:14",
"extensions": [
"dbaeumer.vscode-eslint"
],
"forwardPorts": [3000],
"postCreateCommand": "npm install"
}
- Open the project in VS Code and click “Reopen in Container”
Docker Compose: Managing Multiple Containers
Docker Compose lets you define and run multi-container applications:
Create a docker-compose.yml
file:
yamlCopyversion: '3'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./website:/usr/share/nginx/html
depends_on:
- db
db:
image: mysql:8.0
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: mysecretpassword
MYSQL_DATABASE: mydatabase
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
depends_on:
- db
volumes:
mysql-data:
Run your multi-container setup with:
docker-compose up -d
Stop everything with:
docker-compose down
Time-Saving Docker Containers
Here are some ready-to-use containers for popular applications:
Portainer – Docker Management UI
docker run -d \
-p 9000:9000 \
--name portainer \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
Access at http://localhost:9000
Nextcloud – Your Personal Cloud
docker run -d \
--name nextcloud \
-p 8082:80 \
-v nextcloud:/var/www/html \
nextcloud
Access at http://localhost:8082
Grafana – Analytics & Monitoring
docker run -d \
--name=grafana \
-p 3000:3000 \
grafana/grafana
Access at http://localhost:3000 (default login: admin/admin)
Jenkins – CI/CD Pipeline
docker run -d \
--name jenkins \
-p 8083:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
Access at http://localhost:8083
Best Practices
- Use Official Images: Always start with official images from Docker Hub when possible
- Keep Images Small: Use Alpine-based images when available
- Don’t Run as Root: Use the USER instruction in your Dockerfile
- Use .dockerignore: Exclude unnecessary files
- Use Volumes for Persistence: Don’t store data in containers
- One Process Per Container: Follow the single responsibility principle
- Use Environment Variables: For configuration
- Tag Your Images: Don’t rely on the latest tag
Troubleshooting
- Container won’t start:
docker logs container-name
- See running containers:
docker ps
- See all containers (including stopped):
docker ps -a
- Remove all stopped containers:
docker container prune
- Remove unused images:
docker image prune
Next Steps
- Learn more about Docker networking
- Explore Docker Swarm for container orchestration
- Look into Kubernetes for production deployments
- Create your own Docker images
- Implement CI/CD pipelines with Docker
Conclusion
Congratulations! You’ve taken your first steps into the world of Docker. You now have the knowledge to containerize your applications, create development environments, and deploy services with ease. Keep experimenting and soon you’ll be creating your own sophisticated Docker-based solutions.
Remember: Docker isn’t just a tool; it’s a new way of thinking about software development and deployment. Embrace the containerization mindset, and you’ll find yourself building more portable, scala
Happy coding!