Running ERPNext, Odoo and Tally on one small VPS

Notes on consolidating an accounting-automation lab onto a single Contabo box behind Caddy — what fits, what does not, and where the memory actually goes.

If you want to build automation for accounting systems, you need those systems running somewhere you can break them. Cloud trials expire, sandboxes reset, and you cannot point an agent at a demo tenant and learn anything real.

So I consolidated onto one VPS. These are the notes I wish I had at the start.

The shape of it

One box, four cores, 8 GB of RAM. Caddy in front handling TLS automatically, everything else behind it on subdomains:

ServicePurpose
ERPNextFull accounting system of record
OdooSecond ERP for comparison
TallyThe one most Indian SMEs actually use
Chatbot endpointsRead-only query layers over each

What I got wrong first

Underestimating the ERP baseline. ERPNext and Odoo both want more memory at idle than you expect. Running both plus a database each does not leave much headroom on 8 GB. The fix was not a bigger box — it was being honest about which services need to be up simultaneously.

Treating Tally like a Linux citizen. It is a Windows application. Running it under Wine on a server is workable but it is not a service in the systemd sense, and it does not behave like one. Budget time for this specifically.

Reaching for another vendor too quickly. My first instinct for the tunnelling problem was to add a managed service. The actual answer was a reverse proxy I was already running, on a box I was already paying for. Caddy with automatic Let’s Encrypt certificates removed an entire category of problem for zero additional cost.

The Caddy config is the boring hero

Adding a new service is three lines:

service.example.com {
    reverse_proxy 127.0.0.1:8069
}

Certificates are issued and renewed without intervention. After years of managing certificate rotation by hand in enterprise environments, this still feels slightly unreasonable.

What this enables

The point of all this is not the infrastructure. It is that I can now point an agent at a real ledger with real data, let it attempt a real reconciliation, and see precisely how it fails — then fix it, and try again, without asking anyone’s permission or waiting for a sandbox refresh.

That feedback loop is the whole game.

← All posts