Skip to content

Data Services

Plitho manages stateful data services — NATS, MongoDB, and RabbitMQ (via LavinMQ) — as native systemd processes on the host, with automatic resource limits, storage quotas, and optional scheduled backups.

Overview

Unlike web apps, data services are long-lived background processes that:

  • Run as their own system user (nats, mongod, lavinmq)
  • Listen on a dedicated port on 127.0.0.1 only
  • Have a cgroup slice enforcing CPU and memory limits
  • Have an XFS project quota enforcing disk usage
  • Receive backup timers as systemd .timer units (optional)

All resource usage counts toward your account quota alongside apps and cache instances.

Supported Services

Type Binary Protocol Default Port Range
nats nats-server NATS, JetStream 4222+
mongodb mongod MongoDB wire 27017+
rabbitmq lavinmq AMQP 0-9-1 5672+

RabbitMQ = LavinMQ

The rabbitmq type uses LavinMQ, a Go-native AMQP 0-9-1 broker that is fully compatible with RabbitMQ clients. It requires no Erlang runtime. The management UI is available at port+10000 (e.g. if AMQP is on 5672, management is on 15672).

Creating a Data Service

Dashboard

The creation flow has three steps:

  1. Type Selection — Go to Data ServicesNew Service, choose NATS, MongoDB, or RabbitMQ
  2. Version + Resources — Select the installed version, set CPU/memory/storage, optionally enable backups
  3. Config + Deploy — Fill in service-specific configuration (credentials, protocol settings), then click Deploy

The dashboard shows the connection port and any credentials. Save the password immediately — it is not stored after this response.

REST API

curl -b cookies.txt -X POST https://your-server:8080/api/data-services \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "nats",
    "name": "my-nats",
    "max_cpu_millicores": 500,
    "max_memory_mb": 256,
    "storage_mb": 1024,
    "backup_enabled": true,
    "backup_schedule": "*-*-* 02:00:00",
    "credentials": {"password": "mysecret"}
  }'

Response:

{
  "type": "nats",
  "name": "my-nats",
  "port": 4222,
  "message": "Save the credentials — passwords are not stored after this response."
}

Connecting from Your App

All services bind to 127.0.0.1 only. Use localhost or 127.0.0.1 as the host.

NATS

nats://password@127.0.0.1:4222
nc, err := nats.Connect("nats://password@127.0.0.1:4222")
const nc = await connect({ servers: "nats://127.0.0.1:4222", token: "password" });
nc = await nats.connect("nats://password@127.0.0.1:4222")

MongoDB

mongodb://plitho_<name>:password@127.0.0.1:<port>/admin
client, err := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("MONGODB_URL")))
const client = new MongoClient(process.env.MONGODB_URL);
client = MongoClient(os.environ["MONGODB_URL"])

RabbitMQ (LavinMQ)

amqp://username:password@127.0.0.1:5672/

Management UI: http://127.0.0.1:15672 (port+10000).

conn, err := amqp.Dial(os.Getenv("RABBITMQ_URL"))
const conn = await amqp.connect(process.env.RABBITMQ_URL);
conn = pika.BlockingConnection(pika.URLParameters(os.environ["RABBITMQ_URL"]))

Resource Management

Each service gets a dedicated systemd slice that enforces limits:

Field What it limits
max_cpu_millicores CPU quota via CPUQuota= (1000m = 1 core)
max_memory_mb Hard memory cap via MemoryMax=; soft warning at 80% via MemoryHigh=
storage_mb XFS project quota on the data directory

Minimum values: 100m CPU, 64 MB memory, 100 MB storage.

To update resources:

PUT /api/data-services/{type}/{name}/resources
{"max_cpu_millicores": 1000, "max_memory_mb": 512, "storage_mb": 4096}

This rewrites the slice file and restarts the service.

Credentials

Passwords are passed to the agent on creation and applied to the service config, but are not stored in Plitho's database. Store them in your app's environment variables.

To reset credentials:

POST /api/data-services/{type}/{name}/reset-credentials

A new random password is returned in the response. Plitho restarts the service to apply it.

Configuration

Each service type has a schema defining its configurable fields. The Config tab on the detail page renders these fields dynamically. Fields are annotated with their behavior:

Tag Meaning
Hot reload Applied immediately via runtime command (no restart needed)
Restart required Saved to config, service must restart to take effect
Readonly Cannot be changed after creation

Per-service configuration

NATS

Field Type Default Notes
max_payload number 1048576 Maximum message size in bytes. Restart required.
max_connections number 65536 Maximum concurrent client connections. Restart required.
max_control_line number 4096 Maximum length of control line protocol. Restart required.
write_deadline number 10 Timeout for write operations (seconds). Restart required.
jetstream boolean false Enable persistent messaging. Readonly after creation.

MongoDB

Field Type Default Notes
auth_enabled boolean true Require authentication. Restart required.
storage_engine select wiredTiger Storage engine. Readonly after creation.
cache_size_gb number 0.25 WiredTiger cache size in GB. Hot reload.
max_conns number 1000 Maximum concurrent connections. Hot reload.

RabbitMQ (LavinMQ)

Field Type Default Notes
heartbeat number 60 Heartbeat timeout for client connections (seconds). Restart required.
frame_max number 131072 Maximum frame size (bytes). Restart required.
channel_max number 2048 Maximum number of channels per connection. Restart required.

Updating configuration

PUT /api/data-services/{type}/{name}/config
{
  "config": {"cache_size_gb": 0.5, "max_conns": 2000}
}

Response indicates which changes were applied immediately and which require a restart:

{
  "config": {"cache_size_gb": 0.5, "max_conns": 2000, ...},
  "hot_reload_applied": ["cache_size_gb", "max_conns"],
  "restart_required": [],
  "message": "Changes applied successfully."
}

Backups

Backups are implemented as systemd timer units that run a shell script on a schedule:

plitho-ds-{type}-{name}-backup.timer    ← schedule
plitho-ds-{type}-{name}-backup.service  ← one-shot runner

Backup data is stored at /var/lib/plitho/backups/{type}/{name}/YYYYMMDD-HHMMSS/. Backups older than 7 days are automatically pruned by the backup script.

Per-service strategy

Service Method
NATS Copy of the JetStream store directory
MongoDB mongodump dump into a dated directory
RabbitMQ Copy of the LavinMQ data directory

Configuring backups

PUT /api/data-services/{type}/{name}/backup
{"backup_enabled": true, "backup_schedule": "*-*-* 02:00:00"}

The backup_schedule field is a systemd calendar expression. Examples:

Schedule Meaning
*-*-* 02:00:00 Daily at 02:00
Sun *-*-* 03:00:00 Weekly on Sunday at 03:00
*-*-1 04:00:00 Monthly on the 1st at 04:00

Check backup timer status:

systemctl status plitho-ds-mongodb-mydb-backup.timer
journalctl -u plitho-ds-mongodb-mydb-backup.service

Managing Services

Dashboard

The detail page for each service has seven tabs:

  • Overview — connection details, credentials reset
  • Logs — live streaming of systemd journal output
  • Metrics — CPU, memory, and storage usage over time with charts
  • Resources — update CPU / memory / storage
  • Config — edit service-specific configuration (schema-driven, shows hot reload vs restart required)
  • Backup — enable, disable, or reschedule backups
  • Danger — delete the service and all its data

REST API

Method Endpoint Description
GET /api/data-services List all your services
POST /api/data-services Create a service
GET /api/data-services/{type}/{name} Get service details
DELETE /api/data-services/{type}/{name} Delete service + data
POST /api/data-services/{type}/{name}/restart Restart
PUT /api/data-services/{type}/{name}/resources Update resources
POST /api/data-services/{type}/{name}/reset-credentials New password
PUT /api/data-services/{type}/{name}/config Update configuration
PUT /api/data-services/{type}/{name}/backup Configure backup
GET /api/data-services/{type}/{name}/logs/stream Stream logs (SSE)
GET /api/data-services/{type}/{name}/metrics Get metrics data
GET /api/data-services/{type}/{version}/schema Get config schema

Deleting a Service

Danger

Deletion stops the systemd unit, removes the config file, and permanently deletes the data directory at /var/lib/plitho/ds/{type}/{name}/. Take a backup first.

DELETE /api/data-services/mongodb/mydb

Systemd Units

Each service produces the following units:

plitho-ds-{type}-{name}.service         # main service
plitho-ds-{type}-{name}.slice           # resource limits
plitho-ds-{type}-{name}-backup.service  # backup runner (if enabled)
plitho-ds-{type}-{name}-backup.timer    # backup schedule (if enabled)
# Status
systemctl status plitho-ds-nats-my-nats

# Logs
journalctl -u plitho-ds-nats-my-nats -f

# List all data service units
systemctl list-units 'plitho-ds-*'

Files on Disk

Path Purpose
/etc/plitho/ds/{type}/{name}.conf Service configuration
/var/lib/plitho/ds/{type}/{name}/ Data directory (XFS quota applied)
/var/lib/plitho/backups/{type}/{name}/ Backup archives
/usr/local/lib/plitho/ds/{type}-{name}-backup.sh Backup script
/var/log/plitho/ds/{type}-{name}.log Service log (where applicable)