Tutorials

How to Run Docker and Docker Compose on a Budget Linux VPS (Resource Optimization Guide)

How to Run Docker & Compose on Cheap Linux Cloud VPS (2026) - CpanelFree Guide
Written by Blog

Demystifying Docker on Entry-Level and Budget Cloud VPS

Containerization has transformed application development and server management. However, many system administrators believe that running Docker requires expensive enterprise nodes with 16GB+ RAM. In reality, with proper kernel tuning, cgroup memory limits, optimized container runtimes, and smart swap configuration, you can seamlessly run 10 to 20 production Docker containers—including PostgreSQL databases, Nginx reverse proxies, Redis caches, and API microservices—on an affordable 1GB to 2GB RAM Linux VPS without encountering out-of-memory (OOM) crashes.

In this technical optimization guide, we will walk through installing Docker Engine and Docker Compose V2 on Ubuntu, setting up zRAM and compressed swap partitions, writing resource-capped compose manifests, and implementing automated log-rotation daemons to keep your budget server lightning-fast.

Step 1: Installing Official Docker Engine & Compose V2

Ubuntu’s snap or default universe Docker packages often lag behind upstream performance patches. Always install the official Docker CE repository with modern containerd integration:

# Remove obsolete packages
sudo apt remove -y docker docker-engine docker.io containerd runc

# Add Docker official GPG key and APT repository
sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.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 and Docker Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Enable and start Docker service
sudo systemctl enable --now docker

Step 2: Configuring High-Speed Compressed Swap & zRAM

On memory-constrained VPS instances (1GB or 2GB RAM), unexpected memory spikes can trigger the Linux kernel OOM-killer to instantly terminate database or container daemons. Creating an active NVMe swapfile with optimized swappiness prevents process panics:

# Create a 2GB NVMe swapfile
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Persist swap in fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Tune kernel swappiness to prefer RAM over swap until necessary
sudo sysctl vm.swappiness=15
sudo sysctl vm.vfs_cache_pressure=50
echo 'vm.swappiness=15' | sudo tee -a /etc/sysctl.conf
echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf

Step 3: Global Docker Daemon Log Rotation & Memory Optimization

By default, Docker saves JSON container logs indefinitely, which will quickly consume all remaining disk space on budget SSD drives. Configure global log rotation and default DNS in /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "live-restore": true
}

Apply the configuration with sudo systemctl restart docker. The live-restore flag ensures running containers stay alive even if the Docker daemon restarts.

Step 4: Writing Production Docker Compose with Strict Resource Limits

Always enforce hard CPU and RAM ceilings in your docker-compose.yml manifests using the deploy.resources block to prevent any single buggy container from monopolizing server capacity:

services:
  database:
    image: postgres:16-alpine
    container_name: production_db
    restart: always
    environment:
      POSTGRES_DB: app_prod
      POSTGRES_USER: dbuser
      POSTGRES_PASSWORD: SecretStrongPassword2026!
    volumes:
      - postgres_data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 384M
        reservations:
          memory: 128M

  cache:
    image: redis:7-alpine
    container_name: production_redis
    restart: always
    command: redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru
    deploy:
      resources:
        limits:
          cpus: '0.25'
          memory: 96M

  web_app:
    image: node:20-alpine
    container_name: production_api
    restart: always
    working_dir: /app
    volumes:
      - ./app:/app
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://dbuser:SecretStrongPassword2026!@database:5432/app_prod
    command: ["npm", "start"]
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 300M
    depends_on:
      - database
      - cache

volumes:
  postgres_data:

Docker Resource Consumption & Optimization Benchmarks

Base Image Standard Footprint Alpine/Slim Footprint Idle Memory Usage
PostgreSQL ~380 MB image ~85 MB (alpine) ~32 MB RAM
Redis ~115 MB image ~32 MB (alpine) ~12 MB RAM
Nginx Reverse Proxy ~140 MB image ~23 MB (alpine) ~9 MB RAM
Node.js API ~1.1 GB (full) ~175 MB (slim/alpine) ~48 MB RAM

Essential Routine Docker Maintenance Commands

  • docker stats --no-stream: View instant real-time CPU, RAM, and network I/O per container.
  • docker system prune -af --volumes: Reclaim gigabytes of orphaned build caches and dangling containers.
  • docker compose logs --tail=100 -f <service>: Inspect recent container logs in real time.

Automated Docker Container Updates with Watchtower

Maintaining security on production container fleets requires timely base image updates to patch upstream CVE vulnerabilities. Manually pulling images and restarting dozens of containers across multiple directories is tedious. Watchtower is an open-source containerized utility that monitors your running Docker containers and automatically updates them to the newest image version available on Docker Hub or GitHub Container Registry.

You can deploy Watchtower as a lightweight background container that checks for updates once every 24 hours, cleans up old orphaned images automatically, and sends notifications via webhook:

# Deploy Watchtower daemon with automatic image cleanup
docker run -d   --name watchtower   --restart always   --memory=64m   -v /var/run/docker.sock:/var/run/docker.sock   -e WATCHTOWER_CLEANUP=true   -e WATCHTOWER_SCHEDULE="0 0 4 * * *"   -e WATCHTOWER_INCLUDE_STOPPED=false   containrrr/watchtower

Automated Volume Backup Script for Dockerized Databases

Containers are stateless, but named volumes storing PostgreSQL, MariaDB, or MongoDB data are critical. Create a lightweight cron script in /usr/local/bin/backup-docker-volumes.sh to dump compressed database snapshots directly from running containers without taking them offline:

#!/bin/bash
set -e
BACKUP_DIR="/var/backups/docker/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

# Dump PostgreSQL from running container
docker exec -t production_db pg_dumpall -U dbuser | gzip > $BACKUP_DIR/postgres_all.sql.gz

# Prune backups older than 14 days
find /var/backups/docker/ -type d -mtime +14 -exec rm -rf {} +
echo "Docker database volume backup completed successfully!"

Troubleshooting Common Docker Resource Constraints

  • Error response from daemon: Cannot start container … no space left on device: Run docker system prune -a --volumes to free unreferenced build layers.
  • Killed: out of memory: Inspect dmesg -T | grep oom and verify that container memory limits (e.g. memory: 256M) are enforced in docker-compose.yml.
  • Too many open files: Increase Linux ulimits in /etc/security/limits.conf by adding * soft nofile 65535 and * hard nofile 65535.

Run Lightning-Fast Containers on CpanelFree High-Performance Cloud

Scale your microservices and Docker workloads with dedicated enterprise virtual CPU cores, ultra-low latency NVMe storage, and 100% free hosting solutions.

Claim Free VPS & Hosting →

About the author

Blog

DevOps architect and Linux sysadmin specializing in server hardening, OpenLiteSpeed performance optimization, and free cloud hosting infrastructure.

Leave a Comment