This guide covers the three main tasks you'll perform with Docker.
- Your application code
- A
Dockerfilewith build instructions
Create app.py:
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
response = {"message": "Hello from Docker!"}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(response).encode())
if __name__ == '__main__':
server = HTTPServer(('0.0.0.0', 8000), Handler)
print("Server running on port 8000")
server.serve_forever()Create Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]Build the image:
docker build -t myapp:v1.0 .Verify image was created:
docker images✅ FROM - Base image (Python, Node, etc.)
✅ WORKDIR - Working directory inside container
✅ COPY - Copy files from host to image
✅ EXPOSE - Document which port app uses
✅ CMD - Command to run when container starts
docker run myapp:v1.0docker run -d -p 8080:8000 --name myapp myapp:v1.0Options explained:
-d= Detached mode (run in background)-p 8080:8000= Map host port 8080 to container port 8000--name myapp= Give container a friendly namemyapp:v1.0= Image to use
# Check if running
docker ps
# Test the application
curl http://localhost:8080/
# View logs
docker logs myapp
# View real-time logs
docker logs -f myapp# Stop container
docker stop myapp
# Start stopped container
docker start myapp
# Restart container
docker restart myapp
# Remove container
docker rm myapp
# Force remove running container
docker rm -f myapp# Run single command
docker exec myapp ls -la
# Get interactive shell
docker exec -it myapp sh
# or bash if available
docker exec -it myapp bash✅ -d runs container in background
✅ -p maps ports (host:container)
✅ --name makes management easier
✅ Container keeps running as long as main process runs
✅ Use docker logs to debug issues
Sign up at https://hub.docker.com/signup (free)
docker loginEnter your Docker Hub username and password.
Format: username/repository:tag
docker tag myapp:v1.0 YOUR_USERNAME/myapp:v1.0
docker tag myapp:v1.0 YOUR_USERNAME/myapp:latestWhy tag twice?
v1.0= Specific versionlatest= Most recent version (convention)
docker push YOUR_USERNAME/myapp:v1.0
docker push YOUR_USERNAME/myapp:latest- Go to https://hub.docker.com
- Login and check "Repositories"
- You should see your image!
# Remove local copies
docker rmi YOUR_USERNAME/myapp:v1.0
docker rmi YOUR_USERNAME/myapp:latest
# Pull from registry
docker pull YOUR_USERNAME/myapp:latest
# Run pulled image
docker run -d -p 8080:8000 YOUR_USERNAME/myapp:latestLogin:
echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdinTag:
docker tag myapp:v1.0 ghcr.io/YOUR_USERNAME/myapp:v1.0Push:
docker push ghcr.io/YOUR_USERNAME/myapp:v1.0✅ Must tag with username/repo:tag format
✅ Login before pushing
✅ Anyone can pull public images
✅ Use private repos for sensitive code
✅ Layers are cached (efficient push/pull)
# 1. Create application
mkdir myapp && cd myapp
echo 'print("Hello Docker")' > app.py
# 2. Create Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
EOF
# 3. Build image
docker build -t myapp:v1.0 .
# 4. Test locally
docker run --rm myapp:v1.0
# 5. Tag for registry
docker tag myapp:v1.0 YOUR_USERNAME/myapp:v1.0
# 6. Login and push
docker login
docker push YOUR_USERNAME/myapp:v1.0
# 7. Pull and run from registry
docker pull YOUR_USERNAME/myapp:v1.0
docker run --rm YOUR_USERNAME/myapp:v1.0docker images # List images
docker build -t name:tag . # Build image
docker rmi image # Remove image
docker tag src dst # Tag image
docker push image # Push to registry
docker pull image # Pull from registrydocker ps # List running containers
docker ps -a # List all containers
docker run image # Create and start container
docker start container # Start stopped container
docker stop container # Stop container
docker restart container # Restart container
docker rm container # Remove container
docker logs container # View logs
docker exec -it container sh # Interactive shelldocker system df # Show disk usage
docker container prune # Remove stopped containers
docker image prune -a # Remove unused images
docker volume prune # Remove unused volumes
docker system prune -a # Remove everything unused-
Use specific base image tags
FROM python:3.11-slim # Good FROM python # Avoid (uses latest)
-
Order by change frequency
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . # Dependencies first RUN pip install -r requirements.txt COPY . . # Code last (changes often)
-
Minimize layers
RUN apt-get update && \ apt-get install -y curl vim && \ rm -rf /var/lib/apt/lists/* -
Use .dockerignore
__pycache__ *.pyc .git node_modules .env -
Run as non-root
RUN adduser --disabled-password appuser USER appuser
Create docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "8080:8000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:Commands:
docker compose up -d # Start all services
docker compose ps # List services
docker compose logs # View logs
docker compose down # Stop and removedocker run -p 8081:8000 myapp # Use different host port# Linux: Add user to docker group
sudo usermod -aG docker $USER
# Logout and login againdocker logs container-name # Check logs for errorsdocker build --no-cache -t myapp .# Ensure Docker Desktop/Engine is running
sudo systemctl start docker # Linux- ✅ Complete hands-on labs
- ✅ Read comprehensive theory
- ✅ Practice with real projects
- ✅ Learn Docker Compose for multi-container apps
- ✅ Explore Docker networking and volumes
- ✅ Study Kubernetes for production orchestration
Need help? Check the comprehensive hands-on guide for detailed walkthroughs!