Container Guide

    Basics of Docker on RamNode

    Running containerized applications doesn't have to break the bank. Learn how to leverage RamNode's affordable VPS hosting to deploy and manage lightweight Docker containers, optimize resource usage, and build cost-effective containerized solutions.

    Ubuntu 22.04/24.04
    Docker Engine
    ⏱️ 30-45 minutes

    Prerequisites

    Before starting, ensure you have:

    Server Requirements

    • • RamNode VPS (1GB+ RAM recommended)
    • • Ubuntu 22.04/24.04 or CentOS
    • • Root access to server
    • • SSH client

    Knowledge Requirements

    • • Basic Linux command line
    • • Understanding of containerization
    • • SSH connection skills
    • • Basic Docker concepts
    2

    Why Choose RamNode for Docker Hosting?

    RamNode has carved out a niche in the VPS market by offering high-performance virtual private servers at competitive prices. Here's why it's particularly well-suited for Docker deployments:

    💰 Exceptional Price-to-Performance Ratio

    RamNode's pricing starts at just a few dollars per month for VPS instances with sufficient resources to run multiple lightweight containers. Entry-level plans typically include 1GB RAM, 20GB SSD storage, and generous bandwidth allocations.

    ⚡ SSD Storage Across All Plans

    Unlike many budget providers that still rely on traditional hard drives, RamNode provides SSD and NVMe storage across their entire range. This translates to faster container startup times, improved I/O performance, and better overall application responsiveness.

    🌍 Multiple Data Center Locations

    With locations in the US, Netherlands, and other strategic regions, you can deploy containers closer to your users, reducing latency and improving user experience.

    🔧 KVM Virtualization

    RamNode uses KVM virtualization, providing better isolation and performance compared to OpenVZ containers that many budget providers use. This ensures your Docker containers run in a more predictable environment.

    3

    Initial Server Setup

    Connect to your RamNode VPS and prepare the environment for Docker:

    Connect via SSH
    ssh root@your-server-ip
    Update System Packages
    sudo apt update && sudo apt upgrade -y sudo apt install curl wget git htop unzip -y

    💡 Tip: Replace "your-server-ip" with your actual RamNode VPS IP address.

    4

    Install Docker

    Install Docker using the official installation process:

    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=amd64 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 User to Docker Group
    sudo usermod -aG docker $USER
    Verify Installation
    docker --version docker run hello-world

    ✅ Docker is now installed and ready to use!

    5

    Optimize Docker for Resource-Constrained Environments

    Budget VPS instances often come with limited resources, making optimization crucial:

    Configure Docker Daemon Settings

    Create or modify /etc/docker/daemon.json:

    /etc/docker/daemon.json
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "3"
      },
      "storage-driver": "overlay2",
      "default-ulimits": {
        "nofile": {
          "hard": 65536,
          "soft": 65536
        }
      }
    }

    This configuration limits log file sizes (preventing disk space issues), uses the efficient overlay2 storage driver, and sets appropriate file descriptor limits.

    Enable Swap Accounting

    For better memory management, enable swap accounting in your kernel:

    Enable Swap Accounting
    sudo sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"/' /etc/default/grub sudo update-grub sudo reboot
    6

    Building Lightweight Container Images

    The key to successful budget Docker deployments lies in creating efficient, lightweight images:

    Use Alpine Linux Base Images

    Alpine Linux is a security-oriented, lightweight Linux distribution that's perfect for containers. Alpine-based images are typically 5-10 times smaller than their Ubuntu counterparts:

    Dockerfile with Alpine
    # Instead of this:
    # FROM node:16
    
    # Use this:
    FROM node:16-alpine
    
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci --only=production && npm cache clean --force
    COPY . .
    
    EXPOSE 3000
    CMD ["node", "index.js"]

    Multi-Stage Builds

    Multi-stage builds allow you to separate build dependencies from runtime dependencies, significantly reducing final image size:

    Multi-Stage Dockerfile
    # Build stage
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    
    # Production stage
    FROM node:16-alpine AS production
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci --only=production && npm cache clean --force
    COPY --from=builder /app/dist ./dist
    EXPOSE 3000
    CMD ["node", "dist/index.js"]

    Optimize Layer Caching

    Structure your Dockerfile to maximize layer caching:

    Optimized Dockerfile Structure
    FROM node:16-alpine
    
    WORKDIR /app
    
    # Copy package files first (changes less frequently)
    COPY package*.json ./
    RUN npm ci --only=production
    
    # Copy application code last (changes more frequently)
    COPY . .
    
    EXPOSE 3000
    CMD ["node", "index.js"]
    7

    Resource Management and Monitoring

    Effective resource management is crucial when running containers on budget hardware:

    Setting Resource Limits

    Always set memory and CPU limits for your containers to prevent resource contention:

    Docker Run with Resource Limits
    # Limit container to 512MB RAM and 0.5 CPU cores docker run -d --name myapp --memory=512m --cpus="0.5" myapp:latest
    Docker Compose with Resource Limits
    version: '3.8'
    services:
      web:
        image: myapp:latest
        deploy:
          resources:
            limits:
              memory: 512M
              cpus: '0.5'
            reservations:
              memory: 256M
              cpus: '0.25'

    Monitoring Resource Usage

    Regular monitoring helps identify optimization opportunities:

    Monitor Container Resources
    # Monitor all container resource usage docker stats # Monitor specific container docker stats container_name # Get detailed container information docker inspect container_name
    8

    Practical Deployment Examples

    Let's explore some real-world deployment scenarios that work well on RamNode's budget-friendly infrastructure:

    Web Application Stack

    A typical web application stack with nginx, application server, and database:

    docker-compose.yml - Web Stack
    version: '3.8'
    
    services:
      nginx:
        image: nginx:alpine
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
          - ./ssl:/etc/nginx/ssl:ro
        deploy:
          resources:
            limits:
              memory: 128M
              cpus: '0.2'
        restart: unless-stopped
    
      app:
        build: .
        environment:
          - NODE_ENV=production
          - DATABASE_URL=postgresql://user:pass@db:5432/myapp
        deploy:
          resources:
            limits:
              memory: 512M
              cpus: '0.5'
        restart: unless-stopped
        depends_on:
          - db
    
      db:
        image: postgres:13-alpine
        environment:
          - POSTGRES_DB=myapp
          - POSTGRES_USER=user
          - POSTGRES_PASSWORD=pass
        volumes:
          - postgres_data:/var/lib/postgresql/data
        deploy:
          resources:
            limits:
              memory: 256M
              cpus: '0.3'
        restart: unless-stopped
    
    volumes:
      postgres_data:

    Microservices Architecture

    For microservices, focus on lightweight, single-purpose containers:

    docker-compose.yml - Microservices
    version: '3.8'
    
    services:
      auth-service:
        image: auth-service:alpine
        ports:
          - "3001:3000"
        environment:
          - JWT_SECRET=${JWT_SECRET}
        deploy:
          resources:
            limits:
              memory: 256M
              cpus: '0.25'
    
      api-gateway:
        image: api-gateway:alpine
        ports:
          - "8080:8080"
        environment:
          - AUTH_SERVICE_URL=http://auth-service:3000
          - USER_SERVICE_URL=http://user-service:3000
        deploy:
          resources:
            limits:
              memory: 256M
              cpus: '0.25'
        depends_on:
          - auth-service
          - user-service
    
      user-service:
        image: user-service:alpine
        environment:
          - DATABASE_URL=${DATABASE_URL}
        deploy:
          resources:
            limits:
              memory: 256M
              cpus: '0.25'
    9

    Cost Optimization Strategies

    Maximizing value from your RamNode investment requires strategic planning and ongoing optimization:

    Image Size Optimization

    • • Use .dockerignore files to exclude unnecessary files from build context
    • • Remove package managers and build tools from production images
    • • Combine RUN commands to reduce layers
    • • Use specific package versions to avoid cache invalidation

    Efficient Data Management

    Volume Configuration
    # Use named volumes for persistent data
    volumes:
      app_data:
        driver: local
        driver_opts:
          type: none
          o: bind
          device: /opt/app-data
    
    # Implement log rotation
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

    Automated Cleanup

    Implement automated cleanup to prevent disk space issues:

    cleanup-docker.sh
    #!/bin/bash
    # cleanup-docker.sh
    
    # Remove unused containers
    docker container prune -f
    
    # Remove unused images
    docker image prune -f
    
    # Remove unused volumes
    docker volume prune -f
    
    # Remove unused networks
    docker network prune -f
    
    # Schedule with cron
    # 0 2 * * * /opt/scripts/cleanup-docker.sh
    10

    Security Best Practices

    Running containers on budget infrastructure doesn't mean compromising on security:

    Container Security

    • • Run containers as non-root users when possible
    • • Use official or verified base images
    • • Regularly update base images and dependencies
    • • Implement resource limits to prevent DoS attacks
    • • Use Docker secrets for sensitive data
    Non-root User in Dockerfile
    # Create non-root user
    RUN addgroup -g 1001 -S nodejs
    RUN adduser -S nextjs -u 1001
    
    # Switch to non-root user
    USER nextjs

    Network Security

    Configure proper network isolation:

    Network Isolation
    networks:
      frontend:
        driver: bridge
      backend:
        driver: bridge
        internal: true
    
    services:
      web:
        networks:
          - frontend
    
      app:
        networks:
          - frontend
          - backend
    
      db:
        networks:
          - backend
    11

    Scaling and Load Balancing

    As your applications grow, you'll need strategies for scaling within budget constraints:

    Horizontal Scaling with Docker Swarm

    Docker Swarm provides a lightweight orchestration solution that works well on multiple RamNode instances:

    Docker Swarm Setup
    # Initialize swarm on manager node
    docker swarm init --advertise-addr <manager-ip>
    
    # Join worker nodes
    docker swarm join --token <worker-token> <manager-ip>:2377
    
    # Deploy stack with replicas
    docker service create --replicas 3 --name web-service nginx:alpine

    Load Balancing with Traefik

    Traefik provides automatic service discovery and load balancing:

    Traefik Load Balancer
    version: '3.8'
    
    services:
      traefik:
        image: traefik:v2.9
        command:
          - --api.dashboard=true
          - --providers.docker=true
          - --entrypoints.web.address=:80
        ports:
          - "80:80"
          - "8080:8080"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
    
      app:
        image: myapp:latest
        deploy:
          replicas: 3
          labels:
            - "traefik.enable=true"
            - "traefik.http.routers.app.rule=Host(`myapp.example.com`)"
    12

    Troubleshooting Common Issues

    Budget VPS deployments can present unique challenges. Here are solutions to common problems:

    📞 Need Help? RamNode provides excellent support for VPS-related issues. For Docker-specific problems, the Docker community and documentation are valuable resources.

    🎉 Congratulations!

    You've successfully learned the basics of running Docker on RamNode! Your containerized applications are now running efficiently on budget-friendly infrastructure.