VPS for Freelancers: How to Run Your Entire Business on One Server

VPS for Freelancers: How to Run Your Entire Business on One Server

Freelancers and independent developers pay for a fragmented collection of SaaS tools — Notion for notes, Trello for projects, Basecamp for clients, Calendly for bookings, Mailchimp for newsletters, Squarespace for the portfolio, Dropbox for files. Add it up and you’re paying $200–500/month for tools that share your data with a dozen companies and lock you into their platforms.

A $20–50/month VPS can replace most or all of this. This guide shows exactly how to consolidate your freelance business onto a single self-hosted server — client sites, project management, invoicing, file storage, email, and more.

The Freelancer SaaS Stack (and What It Costs)

Tool Category Common SaaS Monthly Cost Self-Hosted Alternative
Portfolio/website Squarespace, Webflow $16–36 Hugo/Jekyll on Nginx
Client sites (5) Shared hosting × 5 $25–75 Nginx virtual hosts
Project management Basecamp, Asana $15–30 Plane, Taiga
Invoicing FreshBooks, Wave $0–30 InvoiceNinja
File storage Dropbox, Google Drive $10–20 Nextcloud
Git repositories GitHub private $4–20 Gitea
Password manager 1Password, Bitwarden $3–5 Vaultwarden
Uptime monitoring Pingdom $15–50 UptimeKuma
Total $88–266/mo $20–50/mo (VPS)

💡 VPS.DO Tip: A 4 vCPU / 8 GB RAM VPS comfortably runs all of these simultaneously. VPS.DO’s USA VPS plans start at $20/month with 500 GB SSD. View Plans →


The Freelancer VPS Stack

Core infrastructure

  • Ubuntu 22.04 LTS (OS)
  • Nginx (web server and reverse proxy)
  • Docker + Docker Compose (application isolation)
  • Let’s Encrypt / Certbot (free SSL for all domains)
  • MariaDB or PostgreSQL (database)
  • Redis (caching and sessions)

Business applications (all self-hosted)

  • Nextcloud — File storage, contacts, calendar, document editing
  • InvoiceNinja — Professional invoicing, client portal, time tracking
  • Plane or Taiga — Project and task management
  • Gitea — Private Git repositories for client code
  • Vaultwarden — Password manager (Bitwarden-compatible)
  • Uptime Kuma — Monitor all client sites from one dashboard

Step 1: Initial VPS Setup

sudo apt update && sudo apt upgrade -y
sudo apt install nginx docker.io docker-compose certbot python3-certbot-nginx -y
sudo systemctl enable nginx docker
sudo usermod -aG docker $USER
newgrp docker
# Create directory structure
sudo mkdir -p /var/www/portfolio
sudo mkdir -p /var/apps/{nextcloud,invoice,gitea,kuma,vaultwarden}
sudo chown -R $USER:$USER /var/apps

Step 2: Deploy Nextcloud (File Storage + Collaboration)

nano /var/apps/nextcloud/docker-compose.yml
version: '3.8'
services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped
    volumes:
      - nextcloud_data:/var/www/html
      - /var/apps/nextcloud/data:/var/www/html/data
    environment:
      - MYSQL_HOST=db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=SecurePass123!
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.yourdomain.com
    networks:
      - proxy-network

  db:
    image: mariadb:10.11
    container_name: nextcloud-db
    restart: unless-stopped
    volumes:
      - nextcloud_db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=RootPass123!
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=SecurePass123!
    networks:
      - proxy-network

volumes:
  nextcloud_data:
  nextcloud_db:

networks:
  proxy-network:
    external: true
docker network create proxy-network 2>/dev/null || true
cd /var/apps/nextcloud && docker compose up -d

Nginx config for Nextcloud

sudo nano /etc/nginx/sites-available/cloud.yourdomain.com
server {
    listen 80;
    server_name cloud.yourdomain.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    server_name cloud.yourdomain.com;
    ssl_certificate /etc/letsencrypt/live/cloud.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.yourdomain.com/privkey.pem;

    client_max_body_size 10G;
    proxy_read_timeout 300s;

    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

    location / {
        proxy_pass http://nextcloud:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Step 3: Deploy InvoiceNinja (Invoicing)

nano /var/apps/invoice/docker-compose.yml
version: '3.8'
services:
  invoiceninja:
    image: invoiceninja/invoiceninja:latest
    container_name: invoiceninja
    restart: unless-stopped
    volumes:
      - ./storage:/var/www/app/storage
      - ./public:/var/www/app/public
    environment:
      - APP_URL=https://invoice.yourdomain.com
      - DB_HOST=invoice-db
      - DB_DATABASE=invoiceninja
      - DB_USERNAME=ninja
      - DB_PASSWORD=NinjaPass123!
      - APP_KEY=base64:YOUR_32_CHAR_KEY_HERE
    networks:
      - proxy-network

  invoice-db:
    image: mariadb:10.11
    container_name: invoice-db
    restart: unless-stopped
    volumes:
      - invoice_db:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=invoiceninja
      - MYSQL_USER=ninja
      - MYSQL_PASSWORD=NinjaPass123!
      - MYSQL_ROOT_PASSWORD=RootPass123!
    networks:
      - proxy-network

volumes:
  invoice_db:

networks:
  proxy-network:
    external: true
cd /var/apps/invoice && docker compose up -d

Step 4: Deploy Uptime Kuma (Client Site Monitoring)

docker run -d \
  --name uptime-kuma \
  --network proxy-network \
  --restart unless-stopped \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:latest

Add each client site as a monitor in the Uptime Kuma dashboard. You’ll receive instant email/Telegram/Slack notifications when any client site goes down — before the client notices.

Step 5: Deploy Vaultwarden (Password Manager)

docker run -d \
  --name vaultwarden \
  --network proxy-network \
  --restart unless-stopped \
  -v vaultwarden_data:/data \
  -e SIGNUPS_ALLOWED=false \
  -e ADMIN_TOKEN=your-secure-admin-token \
  vaultwarden/server:latest

Access at https://vault.yourdomain.com. Disable public signups and use it as your personal password vault — compatible with the official Bitwarden browser extension and mobile apps.

Step 6: Portfolio and Client Sites with Nginx

# Your portfolio (Hugo static site)
sudo mkdir -p /var/www/yourdomain.com
rsync -avz ./public/ /var/www/yourdomain.com/

# Client sites (WordPress via LEMP)
sudo mkdir -p /var/www/client1.com
# ... standard WordPress setup per site

Step 7: Automated Backups for Everything

nano ~/backup-freelancer.sh
#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/var/backups/freelancer/$DATE"
mkdir -p $BACKUP_DIR

# Backup all Docker volumes
docker run --rm \
  -v uptime-kuma:/data \
  -v $BACKUP_DIR:/backup \
  alpine tar czf /backup/uptime-kuma.tar.gz -C /data .

docker run --rm \
  -v vaultwarden_data:/data \
  -v $BACKUP_DIR:/backup \
  alpine tar czf /backup/vaultwarden.tar.gz -C /data .

# Backup all databases
docker exec nextcloud-db mysqldump -u root -pRootPass123! --all-databases \
  | gzip > $BACKUP_DIR/databases.sql.gz

# Backup client website files
tar czf $BACKUP_DIR/websites.tar.gz /var/www/

# Sync to a second VPS (optional)
rsync -avz $BACKUP_DIR/ backup@BACKUP_VPS_IP:/backups/

# Remove backups older than 30 days
find /var/backups/freelancer -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;

echo "Backup complete: $DATE"
chmod +x ~/backup-freelancer.sh
crontab -e
# 0 2 * * * /bin/bash /root/backup-freelancer.sh

The Freelancer VPS Monthly Cost Breakdown

Component Self-hosted cost SaaS equivalent
VPS (4 GB RAM, 500 GB SSD) $20/month $88–266/month
Domain name $10–15/year Usually included above
SSL certificates $0 (Let’s Encrypt) $0–100/year
Backup storage $0–5/month Often extra
Total ~$21–26/month $88–300/month

Annual savings: $800–3,300/year — for a freelancer, that’s a meaningful amount.


Time Investment: Is It Worth It?

The honest answer: self-hosting requires an upfront time investment (5–10 hours to set everything up) and ongoing maintenance (1–2 hours/month for updates, monitoring, and backups). If your time is worth $100+/hour, crunch the numbers carefully.

The sweet spot: if you’re a developer or technical freelancer who already knows Linux basics, self-hosting your business tools is a Saturday afternoon project that saves hundreds of dollars per year and gives you skills directly applicable to client work.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!