VPS Project Specs: Dev Tools and Automation

15 Coding Agent-Ready Specs | 1 CPU / 1 GB RAM / 20 GB Disk VPS
Part 2 of 3

🐱 Gitea

RAM: ~50 MB | Tech: Go
50 MB RAMGoDockerMust-Have

Lightweight GitHub alternative. Single Go binary, includes git hosting, issues, PRs, CI webhooks, wiki, packages, built-in SSH.

Architecture

+--------+    HTTPS    +--------+     +-------+
|Developer|<===========>| Gitea  |<===>|PostgreS|
| Git CLI |  SSH:2222   | :3000  |     |  / SQLite
+--------+             +--------+     +-------+

Docker Compose

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      USER_UID: 1000
      USER_GID: 1000
      GITEA__database__DB_TYPE: postgres
      GITEA__database__HOST: gitea-db:5432
      GITEA__database__NAME: gitea
      GITEA__database__USER: gitea
      GITEA__database__PASSWD: changeme
    volumes:
      - ./gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:22"
    depends_on: [gitea-db]
    restart: unless-stopped
  gitea-db:
    image: postgres:15-alpine
    container_name: gitea-db
    environment:
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: changeme
      POSTGRES_DB: gitea
    volumes:
      - ./gitea-db:/var/lib/postgresql/data
    restart: unless-stopped

Caddy Reverse Proxy

git.example.com {
  reverse_proxy gitea:3000
}

Security Hardening

Backup Strategy

Dump all repos: gitea dump or backup gitea-data/ and gitea-db/

Health Check

curl -s http://localhost:3000/api/v1/version

🐙 Forgejo

RAM: ~50 MB | Tech: Go
50 MB RAMGoDocker

Community-driven Gitea fork with ActivityPub federation, better CI, stronger FOSS focus. Same lightweight footprint.

Architecture

Developer --> Forgejo (:3000) --> ActivityPub
                    |
               Git Repos
               Issues
               PRs
               Wiki

Docker Compose

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:latest
    container_name: forgejo
    environment:
      USER_UID: 1000
      USER_GID: 1000
    volumes:
      - ./forgejo-data:/data
    ports:
      - "3000:3000"
      - "2222:22"
    restart: unless-stopped

Caddy Reverse Proxy

forgejo.example.com {
  reverse_proxy forgejo:3000
}

Security Hardening

Backup Strategy

Backup forgejo-data/ directory

Health Check

curl -s http://localhost:3000/api/v1/version

🌱 Caddy

RAM: ~10 MB | Tech: Go
10 MB RAMGoMust-Have

The web server that makes HTTPS automatic. Single binary, automatic Let's Encrypt, reverse proxy, file server. Write a 3-line Caddyfile and done.

Architecture

Internet --> Caddy (:80/:443) --> Services
              |
         Auto HTTPS
         Reverse Proxy
         Rate Limiting
         Compression

Docker Compose

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy-data:/data
      - ./caddy-config:/config
    restart: unless-stopped

Caddy Reverse Proxy

# Caddy IS the reverse proxy. Example Caddyfile:
# app.example.com { reverse_proxy app:8080 }

Security Hardening

Backup Strategy

Backup Caddyfile and caddy-data/ (certs, keys)

Health Check

curl -sI https://localhost | head -3

🌊 Nginx

RAM: ~5 MB | Tech: C
5 MB RAMCEasy

Battle-tested reverse proxy, load balancer, static file server, caching. Configure once, forget forever.

Architecture

Internet --> Nginx (:80/:443) --> Backend Services
              |
         Load Balancing
         Caching
         Rate Limiting

Docker Compose

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./sites:/etc/nginx/conf.d
      - ./certs:/etc/nginx/certs:ro
    restart: unless-stopped

Caddy Reverse Proxy

# Use Caddy instead for auto-HTTPS.
# If using Nginx, manage certs manually with certbot.

Security Hardening

Backup Strategy

Backup nginx.conf, sites/, and certs/

Health Check

curl -sI http://localhost

🐍 Woodpecker CI

RAM: ~30 MB | Tech: Go
30 MB RAMGoDocker

Lightweight CI/CD that runs as single binary + Docker agent. YAML pipelines, integrates with Gitea/GitHub.

Architecture

Git Push --> Woodpecker Server (:8000) --> Agent --> Docker
                |
           Webhook
           Pipeline
           Execution

Docker Compose

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:latest
    container_name: woodpecker
    environment:
      WOODPECKER_HOST: https://ci.example.com
      WOODPECKER_GITEA: "true"
      WOODPECKER_GITEA_URL: http://gitea:3000
      WOODPECKER_GITEA_CLIENT: your-client-id
      WOODPECKER_GITEA_SECRET: your-secret
      WOODPECKER_AGENT_SECRET: changeme
    volumes:
      - ./woodpecker-data:/var/lib/woodpecker
    ports:
      - "8000:8000"
    restart: unless-stopped
  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:latest
    container_name: woodpecker-agent
    environment:
      WOODPECKER_SERVER: woodpecker:9000
      WOODPECKER_AGENT_SECRET: changeme
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on: [woodpecker-server]
    restart: unless-stopped

Caddy Reverse Proxy

ci.example.com {
  reverse_proxy woodpecker:8000
}

Security Hardening

Backup Strategy

Backup woodpecker-data/ directory

Health Check

curl -s http://localhost:8000/api/version

⚡ n8n

RAM: ~100 MB | Tech: Node.js
100 MB RAMNode.jsDocker

Self-hosted Zapier alternative. Visual workflow builder with 300+ integrations. Connect APIs, webhooks, databases with drag-and-drop.

Architecture

Trigger (Webhook/Cron/API) --> n8n (:5678) --> Action (HTTP/DB/Email)
                                |
                           Workflow Engine
                           300+ Integrations

Docker Compose

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    environment:
      N8N_HOST: n8n.example.com
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://n8n.example.com
      N8N_BASIC_AUTH_ACTIVE: "true"
      N8N_BASIC_AUTH_USER: admin
      N8N_BASIC_AUTH_PASSWORD: changeme
    volumes:
      - ./n8n-data:/home/node/.n8n
    ports:
      - "5678:5678"
    restart: unless-stopped

Caddy Reverse Proxy

n8n.example.com {
  reverse_proxy n8n:5678
}

Security Hardening

Backup Strategy

Backup n8n-data/ directory (workflows + credentials)

Health Check

curl -s http://localhost:5678/healthz

🔨 Huginn

RAM: ~150 MB | Tech: Ruby
150 MB RAMRubyDocker

Create agents that monitor and act on your behalf. Scrape websites, watch RSS feeds, send notifications. Your own IFTTT.

Architecture

Web/RSS/API --> Huginn Agent (:3000) --> Action
                   |
              Event Pipeline
              Scheduling
              Webhooks

Docker Compose

services:
  huginn:
    image: ghcr.io/huginn/huginn:latest
    container_name: huginn
    environment:
      HUGINN_DATABASE_ADAPTER: postgresql
      HUGINN_DATABASE_HOST: huginn-db
      HUGINN_DATABASE_USERNAME: huginn
      HUGINN_DATABASE_PASSWORD: changeme
      HUGINN_SEED_DATABASE: "true"
    ports:
      - "3000:3000"
    depends_on: [huginn-db]
    restart: unless-stopped
  huginn-db:
    image: postgres:15-alpine
    container_name: huginn-db
    environment:
      POSTGRES_USER: huginn
      POSTGRES_PASSWORD: changeme
      POSTGRES_DB: huginn
    volumes:
      - ./huginn-db:/var/lib/postgresql/data
    restart: unless-stopped

Caddy Reverse Proxy

huginn.example.com {
  reverse_proxy huginn:3000
}

Security Hardening

Backup Strategy

Dump DB: pg_dump huginn > backup.sql

Health Check

curl -s http://localhost:3000/ | grep -q Huginn

📅 changedetection.io

RAM: ~50 MB | Tech: Python
50 MB RAMPythonDocker

Monitor websites for changes and get notified. Track price drops, news updates. Visual selector, JSON API, screenshot diffs.

Architecture

URLs --> changedetection (:5000) --> Notifications
                    |
               Diff Engine
               Visual Selector
               Screenshots

Docker Compose

services:
  changedetection:
    image: ghcr.io/dgtlmoon/changedetection.io:latest
    container_name: changedetection
    volumes:
      - ./cd-data:/datastore
    ports:
      - "5000:5000"
    restart: unless-stopped

Caddy Reverse Proxy

changedetection.example.com {
  reverse_proxy changedetection:5000
}

Security Hardening

Backup Strategy

Backup cd-data/ directory

Health Check

curl -s http://localhost:5000/ | grep -q changedetection

📊 Netdata

RAM: ~50 MB | Tech: C
50 MB RAMCOne-LinerMust-Have

Real-time performance monitoring with beautiful dashboards. Zero config, auto-detects everything. CPU, RAM, disk, network, Docker, 800+ integrations.

Architecture

System --> Netdata (:19999) --> Dashboard
              |
         Metrics Collector
         Streaming
         Alerts

Docker Compose

services:
  netdata:
    image: netdata/netdata:latest
    container_name: netdata
    hostname: myserver
    volumes:
      - ./netdata-config:/etc/netdata
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "19999:19999"
    cap_add: [SYS_PTRACE]
    restart: unless-stopped

Caddy Reverse Proxy

monitor.example.com {
  reverse_proxy netdata:19999
}

Security Hardening

Backup Strategy

Config is auto-generated. Backup netdata-config/ for custom settings.

Health Check

curl -s http://localhost:19999/api/v1/info

🛠 Uptime Kuma

RAM: ~30 MB | Tech: Node.js
30 MB RAMNode.jsDockerMust-Have

Beautiful uptime monitoring. Monitor HTTP(s), TCP, DNS, Docker. Slack/Discord/Telegram notifications. The prettiest status page ever.

Architecture

Services --> Uptime Kuma (:3001) --> Status Page
                 |
            Ping/HTTP Check
            Notifications
            90+ Integrations

Docker Compose

services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    volumes:
      - ./uptime-kuma-data:/app/data
    ports:
      - "3001:3001"
    restart: unless-stopped

Caddy Reverse Proxy

status.example.com {
  reverse_proxy uptime-kuma:3001
}

Security Hardening

Backup Strategy

Backup uptime-kuma-data/ directory (SQLite DB)

Health Check

curl -s http://localhost:3001/metrics

📝 GoAccess

RAM: ~5 MB | Tech: C
5 MB RAMCEasy

Real-time web log analyzer. Terminal UI or HTML reports. Analyze nginx/caddy logs instantly.

Architecture

Nginx/Caddy Logs --> GoAccess --> Terminal UI
                       |         or
                  Parse/Analyze   HTML Report
                       |
                  Real-time

Docker Compose

services:
  goaccess:
    image: allinurl/goaccess:latest
    container_name: goaccess
    volumes:
      - /var/log/nginx:/var/log/nginx:ro
      - ./goaccess-reports:/srv/report
    ports:
      - "7890:7890"
    command: goaccess /var/log/nginx/access.log -o /srv/report/index.html --log-format=COMBINED --real-time-html
    restart: unless-stopped

Caddy Reverse Proxy

goaccess.example.com {
  reverse_proxy goaccess:7890
}

Security Hardening

Backup Strategy

Generated reports are in goaccess-reports/. Re-run to update.

Health Check

goaccess /var/log/nginx/access.log --log-format=COMBINED

📋 PrivateBin

RAM: ~10 MB | Tech: PHP/JS
10 MB RAMPHPDocker

Client-side encrypted pastebin. Zero knowledge on server. Burn-after-reading, password protection, syntax highlighting.

Architecture

User --> PrivateBin (:8080) --> Encrypted Storage
              |
         Client-side
         Encryption
         Zero Knowledge

Docker Compose

services:
  privatebin:
    image: privatebin/nginx-fpm-alpine:latest
    container_name: privatebin
    volumes:
      - ./privatebin-data:/srv/data
    ports:
      - "8080:80"
    restart: unless-stopped

Caddy Reverse Proxy

paste.example.com {
  reverse_proxy privatebin:80
}

Security Hardening

Backup Strategy

Backup privatebin-data/ directory (encrypted pastes)

Health Check

curl -s http://localhost:80/ | grep -q PrivateBin

📤 Lufi

RAM: ~30 MB | Tech: Perl
30 MB RAMPerlDocker

Encrypted file sharing. Files encrypted client-side before upload. Set expiry dates, download limits, passwords.

Architecture

User --> Lufi (:8181) --> Encrypted File Storage
              |
         Client-side
         Encryption
         Expiration

Docker Compose

services:
  lufi:
    image: lucasgreff/lufi:latest
    container_name: lufi
    volumes:
      - ./lufi-data:/data
    ports:
      - "8181:8181"
    environment:
      CONTACT: admin@example.com
      MAX_FILE_SIZE: 100000000
    restart: unless-stopped

Caddy Reverse Proxy

lufi.example.com {
  reverse_proxy lufi:8181
}

Security Hardening

Backup Strategy

Backup lufi-data/ directory

Health Check

curl -sI http://localhost:8181/

✂ MicroBin

RAM: ~5 MB | Tech: Rust
5 MB RAMRustOne Binary

Tiny self-contained pastebin and file server in Rust. Single binary, no database, supports URLs, file uploads, raw serving, expiration.

Architecture

User --> MicroBin (:8080) --> File Storage
              |
         Pastes
         File Uploads
         URLs
         Raw Serving

Docker Compose

services:
  microbin:
    image: databros/microbin:latest
    container_name: microbin
    environment:
      MICROBIN_ADMIN_USERNAME: admin
      MICROBIN_ADMIN_PASSWORD: changeme
      MICROBIN_SHOW_READ_URLS: "true"
    volumes:
      - ./microbin-data:/app/pasta
    ports:
      - "8080:8080"
    restart: unless-stopped

Caddy Reverse Proxy

microbin.example.com {
  reverse_proxy microbin:8080
}

Security Hardening

Backup Strategy

Backup microbin-data/ directory

Health Check

curl -s http://localhost:8080/ | grep -q MicroBin
Starter Combo (~240 MB total)
Gitea (50 MB) + Caddy (10 MB) + Uptime Kuma (30 MB) + Netdata (50 MB) + n8n (100 MB) = complete dev stack.
Generated by Bob | Back to Index | bob-first-page.pages.dev