Back to articles
Technology Insight

Optimizing Docker Swarm for Low-RAM VPS: How to Smoothly Run Over 20 Containers Alternately

May 30, 2026

Introduction: The Low-RAM Docker Swarm Challenge

In the modern DevOps landscape, containerization has revolutionized how we deploy and manage applications. Docker Swarm offers a native, lightweight clustering solution that is often praised for its simplicity compared to Kubernetes. However, deploying a robust microservices architecture on budget-friendly, low-RAM Virtual Private Servers (VPS)—such as configurations with 1GB to 2GB of memory—presents severe operational hurdles.

Running more than 20 concurrent containers on a resource-constrained node frequently leads to the dreaded Out Of Memory (OOM) killer invoking its wrath, causing spontaneous service outages and system instability. Is it possible to transform a cheap VPS into a resilient, high-density hosting environment? The answer is yes. With strategic kernel tuning, precise resource allocation, and optimized daemon configurations, you can achieve exceptional container density without sacrificing stability.

1. Establishing a Resilient Base: Swap Space Management

When operating in high-density, low-memory environments, your first line of defense is Swap space. While relying on disk-based swap can introduce latency, it acts as a critical safety net to prevent immediate container failure during temporary memory spikes.

Creating and Configuring Optimal Swap

For a VPS with 2GB of RAM, allocating a 2GB to 4GB swap file is highly recommended. Use the following commands to initialize a secure swap space:

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

To ensure this persist across system reboots, append this line to your /etc/fstab file:

/swapfile mercantile swap swap defaults 0 0

Tuning Kernel Swappiness

By default, Linux systems often utilize swap aggressively. For production databases or real-time microservices, excessive swapping degrades performance. We must instruct the kernel to use swap only as an emergency relief valve by reducing the swappiness value. Edit /etc/sysctl.conf and append the following parameters:

  • vm.swappiness=10: Tells the kernel to avoid swapping processes out of physical memory unless absolutely necessary.
  • vm.vfs_cache_pressure=50: Helps reclaim memory used for caching directory and inode objects more efficiently.

2. Optimizing the Docker Daemon for Low Overheads

The Docker daemon itself consumes a non-trivial amount of background resources. When every megabyte counts, default configurations must be trimmed down to reduce the baseline footprint before any application containers even launch.

Switching the Storage Driver

Ensure your storage subsystem is running on overlay2, which is highly efficient regarding memory usage and page-cache sharing among concurrent containers. Avoid legacy drivers like devicemapper or aufs.

Adjusting Log Rotation Profiles

Unbounded container logs can rapidly consume disk space and memory buffers. Define strict logging limits within your global daemon configuration file located at /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
Implementing a system-wide log rotation policy prevents log daemons from locking up precious memory blocks when application traffic surges.

3. Crafting Lean Docker Swarm Service Definitions

Orchestrating more than 20 containers on limited hardware requires absolute strictness within your docker-compose.yml deployment stacks. Unchecked containers will greedily expand, cannibalizing resources from adjacent services.

Implementing Hard Resource Limits

Every service deployed to your Swarm must feature explicitly defined limits and reservations under the deploy key. This ensures the Docker Swarm orchestrator intelligently schedules tasks based on actual available capacity.

version: '3.8'
services:
  web-app:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.20'
          memory: 64M
        reservations:
          cpus: '0.05'
          memory: 32M

By capping the microservices at 64MB thresholds, 20 containers will mathematically consume a predictable baseline of approximately 1.28GB of RAM, leaving an adequate buffer for the OS and Docker engine overheads.

4. Choosing the Right Base Images: The Alpine Imperative

The structural composition of your container images fundamentally dictates their memory footprint. Standard Ubuntu or Debian-based images load extraneous libraries and background dependencies into RAM.

Transitioning to Alpine Linux

Whenever viable, enforce the use of Alpine Linux variants for your service runtimes. Alpine reduces base image sizes from hundreds of megabytes down to less than 5MB. This minimalism correlates directly to minimized run-time memory architectures.

  • Replace node:latest with node:alpine
  • Replace python:3.11 with python:3.11-alpine
  • Replace httpd:latest with httpd:alpine

Optimizing Runtime Environments

Multi-stage Docker builds should be utilized to strip away build-essential compilers, header files, and documentation assets, leaving purely compiled binaries running inside minimal environments.

5. Mitigating Swarm Manager Overhead

In a standard multi-node infrastructure, Docker Swarm distinguishes between Manager and Worker nodes. If you are operating on a single, low-RAM VPS, that node must concurrently act as both manager and worker.

Disabling Extraneous Metrics and Ingress Rules

The Raft consensus protocol used by Swarm managers requires disk and memory cycles to maintain state synchronization. To conserve performance, minimize the frequency of service updates, limit automated health checks to reasonable intervals (e.g., checking every 30 seconds instead of every 5 seconds), and avoid exposing complex mesh networks for services that can communicate internally via private overlay networks.

Conclusion: High Efficiency on a Budget

Maximizing container density on a low-RAM VPS requires a holistic strategy encompassing kernel adjustments, strict resource policing, and disciplined container architecture design. By implementing swap buffers, forcing aggressive limits via docker-compose, and deploying lightweight Alpine-based images, running 20+ containers simultaneously on modest hardware transforms from a technical liability into an elegant, cost-effective reality.

Regularly audit your cluster using docker stats to isolate resource-heavy outliers, and continuously refine your allocation boundaries to preserve a fluid enterprise operation on affordable infrastructures.

Optimizing Docker Swarm for Low-RAM VPS: How to Smoothly Run Over 20 Containers Alternately | DPTCloud