Docker Containers
Deploy and manage containerized applications on your TinyBox VPS
Why Use Docker on TinyBox VPS?
Isolation
Run multiple services without conflicts
Efficiency
Better resource utilization than VMs
Portability
Deploy consistently across environments
Install Docker Engine
Install Docker (Official Method)
# Update system packages
apt update && apt upgrade -y
# Install required packages
apt install apt-transport-https ca-certificates curl gnupg lsb-release -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 Engine
apt update
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Configure Docker
# Start and enable Docker service
systemctl start docker
systemctl enable docker
# Add user to docker group (optional, allows running docker without sudo)
usermod -aG docker $USER
# Test Docker installation
docker --version
docker compose version
# Test with hello-world container
docker run hello-world
Security Note
Adding users to the docker group grants root-equivalent privileges. Only add trusted users to this group.
Essential Docker Commands
Container Management
# Run a container
docker run -d --name myapp nginx:latest
# List running containers
docker ps
# List all containers
docker ps -a
# Stop a container
docker stop myapp
# Start a container
docker start myapp
# Remove a container
docker rm myapp
# View container logs
docker logs myapp
# Execute commands in running container
docker exec -it myapp /bin/bash
Image Management
# List images
docker images
# Pull an image
docker pull ubuntu:22.04
# Remove an image
docker rmi ubuntu:22.04
# Build an image from Dockerfile
docker build -t myapp:latest .
# Tag an image
docker tag myapp:latest myapp:v1.0
# Push to registry
docker push myapp:latest
# Remove unused images
docker image prune
# Remove all unused resources
docker system prune
Deploy Popular Applications
Nginx Web Server
# Run Nginx with port mapping
docker run -d \
--name nginx-server \
-p 8080:80 \
-v /var/www/html:/usr/share/nginx/html:ro \
nginx:latest
# Access: http://your-server-ip:8080
WordPress with MySQL
# Create network
docker network create wordpress-net
# Run MySQL database
docker run -d \
--name wordpress-db \
--network wordpress-net \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppassword \
-v wordpress-db:/var/lib/mysql \
mysql:8.0
# Run WordPress
docker run -d \
--name wordpress-site \
--network wordpress-net \
-p 8081:80 \
-e WORDPRESS_DB_HOST=wordpress-db \
-e WORDPRESS_DB_USER=wpuser \
-e WORDPRESS_DB_PASSWORD=wppassword \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress-files:/var/www/html \
wordpress:latest
# Access: http://your-server-ip:8081
Node.js Application
# Create Dockerfile
cat > Dockerfile << 'EOF'
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
USER node
CMD ["npm", "start"]
EOF
# Build and run
docker build -t my-node-app .
docker run -d --name nodeapp -p 3000:3000 my-node-app
TinyBox VPS Port Mapping
Remember to use your allocated ports (10000 + VPS ID range). Map container ports to your available ports:
# Example for VPS ID 123:
# SSH: 10123, HTTP: 20123, Custom: 30123
docker run -p 20123:80 nginx # Maps container port 80 to your allocated port 20123
Docker Compose for Multi-Container Apps
Complete LAMP Stack Example
# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
web:
image: php:8.1-apache
container_name: lamp-web
ports:
- "8082:80"
volumes:
- ./www:/var/www/html
- ./apache/000-default.conf:/etc/apache2/sites-available/000-default.conf
depends_on:
- database
networks:
- lamp-network
database:
image: mysql:8.0
container_name: lamp-db
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: lampdb
MYSQL_USER: lampuser
MYSQL_PASSWORD: lamppassword
volumes:
- mysql_data:/var/lib/mysql
networks:
- lamp-network
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: lamp-pma
ports:
- "8083:80"
environment:
PMA_HOST: database
PMA_USER: root
PMA_PASSWORD: rootpassword
depends_on:
- database
networks:
- lamp-network
volumes:
mysql_data:
networks:
lamp-network:
driver: bridge
EOF
# Start the stack
docker compose up -d
# View logs
docker compose logs
# Stop the stack
docker compose down
Useful Docker Compose Commands
# Start services
docker compose up -d
# Stop services
docker compose down
# View running services
docker compose ps
# View logs for all services
docker compose logs
# View logs for specific service
docker compose logs web
# Rebuild and restart services
docker compose up -d --build
# Scale a service
docker compose up -d --scale web=3
# Execute command in service
docker compose exec web bash
Docker Security Best Practices
✓ Security Best Practices
- • Use official images from Docker Hub
- • Run containers as non-root user
- • Keep images updated and scan for vulnerabilities
- • Use specific image tags, not 'latest'
- • Limit container resources (CPU, memory)
- • Use secrets management for sensitive data
- • Enable Docker Content Trust
- • Regularly audit running containers
✗ Security Anti-Patterns
- • Never run containers with --privileged
- • Don't include secrets in Dockerfiles
- • Avoid running containers as root
- • Don't expose unnecessary ports
- • Never disable security features
- • Don't use untrusted base images
- • Avoid mounting /var/run/docker.sock
- • Don't ignore security updates
Security Configuration Example
# Secure container run example
docker run -d \
--name secure-app \
--user 1001:1001 \
--read-only \
--tmpfs /tmp \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
--memory 512m \
--cpus 0.5 \
-p 8084:8080 \
myapp:latest
# Scan image for vulnerabilities (using Docker Scout)
docker scout quickview myapp:latest
docker scout cves myapp:latest
Data Persistence and Volumes
Docker Volumes vs Bind Mounts
Docker Volumes (Recommended)
# Create volume
docker volume create myapp-data
# Use volume
docker run -d \
--name myapp \
-v myapp-data:/app/data \
myapp:latest
# List volumes
docker volume ls
# Inspect volume
docker volume inspect myapp-data
Managed by Docker, portable, better performance
Bind Mounts
# Use bind mount
docker run -d \
--name myapp \
-v /host/path:/container/path \
myapp:latest
# Read-only bind mount
docker run -d \
--name myapp \
-v /host/path:/container/path:ro \
myapp:latest
Direct host filesystem access, good for development
Backup and Restore Volumes
# Backup volume to tar file
docker run --rm \
-v myapp-data:/data \
-v $(pwd):/backup \
ubuntu:latest \
tar czf /backup/myapp-data-backup.tar.gz -C /data .
# Restore volume from backup
docker run --rm \
-v myapp-data:/data \
-v $(pwd):/backup \
ubuntu:latest \
bash -c "cd /data && tar xzf /backup/myapp-data-backup.tar.gz"
# Copy data between volumes
docker run --rm \
-v source-volume:/source:ro \
-v target-volume:/target \
ubuntu:latest \
cp -a /source/. /target/
Resource Management and Monitoring
Resource Limits
# Set CPU and memory limits
docker run -d \
--name resource-limited-app \
--cpus="1.5" \
--memory="512m" \
--memory-swap="1g" \
nginx:latest
# Set CPU priority (nice value)
docker run -d \
--name low-priority-app \
--cpu-shares=512 \
nginx:latest
# Limit disk I/O
docker run -d \
--name io-limited-app \
--device-read-bps /dev/sda:1mb \
--device-write-bps /dev/sda:1mb \
nginx:latest
Monitoring Commands
# Monitor resource usage
docker stats
# Monitor specific containers
docker stats container1 container2
# Get resource usage in JSON format
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# Check disk usage
docker system df
# Monitor container processes
docker exec -it container_name top
# View container resource limits
docker inspect container_name | grep -A 20 "Resources"
Resource Planning for TinyBox VPS
TINY 1.0 VPS:
- • 1 vCPU, 1GB RAM
- • Limit containers to ~512MB RAM
- • Run 2-3 lightweight containers max
TINY 2.1 VPS:
- • 2 vCPU, 2GB RAM
- • Can handle more containers
- • Good for Docker Compose stacks
Common Issues & Solutions
Container won't start / exits immediately
Check container logs and ensure correct command/entrypoint:
docker logs container_name
docker run -it --entrypoint=/bin/bash image_name
docker inspect container_name
Out of disk space
Clean up unused Docker resources:
# Remove unused containers, networks, images
docker system prune -a
# Remove specific unused items
docker container prune
docker image prune
docker volume prune
docker network prune
Permission denied / cannot bind to port
Check if port is already in use or if you need elevated privileges:
# Check what's using the port
netstat -tulpn | grep :8080
lsof -i :8080
# Use different port or stop conflicting service
docker run -p 8081:80 nginx # Use different host port
Container networking issues
Debug network connectivity between containers:
# List networks
docker network ls
# Inspect network
docker network inspect bridge
# Test connectivity
docker exec -it container1 ping container2
docker exec -it container1 nslookup container2
✓ Docker Best Practices Checklist
- ✓ Use multi-stage builds for smaller images
- ✓ Set resource limits for containers
- ✓ Use health checks for critical services
- ✓ Implement proper logging strategy
- ✓ Regular security scans and updates
- ✓ Use Docker Compose for multi-container apps
- ✓ Implement backup strategy for volumes
- ✓ Monitor container resource usage