A production guide for running Vector, a high-performance observability data pipeline, on a RamNode VPS as either an agent or an aggregator.
Overview
Vector is an open-source, end-to-end observability data pipeline built in Rust and maintained by Datadog's community open source team. It collects, transforms, and routes logs and metrics from many sources to many destinations, with built-in buffering and retry so delivery survives downstream outages. Its unified architecture means one tool handles logs and metrics instead of a separate agent per data type.
Vector deploys in three roles:
- Agent: runs on a host, collects that host's logs and metrics, and forwards them upstream.
- Aggregator: receives data from many agents, does heavier transformation, and fans out to your storage and analysis backends.
- Unified: a combination of both.
This guide covers installing Vector on a RamNode VPS and configuring it for both roles, with TLS for the aggregator listener and a hardened systemd service. The pipeline is defined in a single vector.yaml built from three component types: sources, transforms, and sinks.
Prerequisites
- A RamNode VPS running Ubuntu 24.04 LTS. A 1 GB plan is fine for an agent; an aggregator handling meaningful throughput wants at least 2 vCPU and 2 to 4 GB RAM.
- Root or sudo access.
- A domain pointing at the VPS if you are running an aggregator with TLS.
- Somewhere to send data: Elasticsearch, Loki, ClickHouse, S3-compatible object storage, or a SaaS backend.
1. Initial server hardening
Create a non-root user:
adduser deploy
usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deployHarden SSH in /etc/ssh/sshd_config (PermitRootLogin no, PasswordAuthentication no), then systemctl reload ssh.
Set the firewall. An agent needs only outbound access. An aggregator needs an inbound port for the source protocol you choose (a common choice is 6000 for the vector source, or 9000 for syslog). Adjust to match your config.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
# Aggregator only: the port your source listens on
sudo ufw allow 6000/tcp
sudo ufw enable2. Install Vector
The install script adds the correct package repository for your distribution and installs the latest release, which also creates a systemd unit.
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev | bashAlternatively, add the apt repository directly for repeatable, apt-managed upgrades:
bash -c "$(curl -L https://setup.vector.dev)"
sudo apt update
sudo apt install -y vectorConfirm the install:
vector --versionThe package installs the config at /etc/vector/vector.yaml and a vector systemd service.
3. A first pipeline to validate the install
Before wiring up real sources, confirm Vector runs end to end with generated data. Replace /etc/vector/vector.yaml with:
sources:
generate_syslog:
type: demo_logs
format: syslog
count: 100
transforms:
remap_syslog:
inputs:
- generate_syslog
type: remap
source: |
structured = parse_syslog!(.message)
. = merge(., structured)
sinks:
emit_console:
inputs:
- remap_syslog
type: console
encoding:
codec: jsonValidate the config, then run it in the foreground:
vector validate /etc/vector/vector.yaml
vector --config /etc/vector/vector.yamlYou should see structured JSON events. The remap transform is the heart of Vector: it runs Vector Remap Language (VRL) to parse, enrich, and reshape events as they flow through. Stop with Ctrl-C once verified.
4. Agent configuration
An agent collects the host's own logs and forwards them to an aggregator or directly to a backend. This example tails the systemd journal and host logs, adds the hostname, and ships to a remote Vector aggregator over TLS.
sources:
host_journal:
type: journald
host_logs:
type: file
include:
- /var/log/*.log
transforms:
add_host:
inputs:
- host_journal
- host_logs
type: remap
source: |
.host = get_hostname!()
.environment = "production"
sinks:
to_aggregator:
inputs:
- add_host
type: vector
address: "aggregator.example.com:6000"
tls:
enabled: true
verify_certificate: true5. Aggregator configuration
An aggregator receives from many agents, applies shared transforms, and routes to your backends. This example accepts data from agents over TLS, drops debug noise, and sends to both Loki and S3-compatible object storage.
sources:
from_agents:
type: vector
address: "0.0.0.0:6000"
tls:
enabled: true
crt_file: /etc/vector/tls/fullchain.pem
key_file: /etc/vector/tls/privkey.pem
transforms:
drop_debug:
inputs:
- from_agents
type: filter
condition: '.level != "debug"'
sinks:
to_loki:
inputs:
- drop_debug
type: loki
endpoint: "https://loki.example.com"
encoding:
codec: json
labels:
host: "{{ host }}"
environment: "{{ environment }}"
archive_s3:
inputs:
- drop_debug
type: aws_s3
bucket: my-log-archive
endpoint: "https://s3.example.com"
region: us-east-1
compression: gzip
encoding:
codec: jsonVector supports dozens of sinks beyond these, including Elasticsearch, ClickHouse, Kafka, Prometheus, Datadog, Honeycomb, and OpenTelemetry. Point the pipeline wherever your stack needs.
6. TLS for the aggregator
Obtain a certificate for the aggregator listener with certbot and place it where Vector reads it:
sudo apt install -y certbot
sudo certbot certonly --standalone -d aggregator.example.com
sudo mkdir -p /etc/vector/tls
sudo cp /etc/letsencrypt/live/aggregator.example.com/fullchain.pem /etc/vector/tls/
sudo cp /etc/letsencrypt/live/aggregator.example.com/privkey.pem /etc/vector/tls/
sudo chown -R vector:vector /etc/vector/tls
sudo chmod 600 /etc/vector/tls/*.pemAdd a renewal deploy hook at /etc/letsencrypt/renewal-hooks/deploy/vector.sh:
#!/bin/bash
cp /etc/letsencrypt/live/aggregator.example.com/fullchain.pem /etc/vector/tls/
cp /etc/letsencrypt/live/aggregator.example.com/privkey.pem /etc/vector/tls/
chown -R vector:vector /etc/vector/tls
chmod 600 /etc/vector/tls/*.pem
systemctl restart vectorsudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/vector.sh7. Run Vector as a service
The package ships a systemd unit. Enable and start it:
sudo systemctl enable --now vector
sudo systemctl status vectorVector runs as the unprivileged vector user by default. For an agent reading the journal, that user must be in the systemd-journal group:
sudo usermod -aG systemd-journal vector
sudo systemctl restart vectorFor files under /var/log, confirm the vector user can read the paths you included, or adjust group membership accordingly.
8. Observing Vector itself
Enable the Vector API to expose a health endpoint and live introspection. Add to your config:
api:
enabled: true
address: "127.0.0.1:8686"The GET /health endpoint on 8686 is stable and suitable for uptime checks and Kubernetes-style probes. Keep the API bound to localhost; do not expose 8686 publicly. Live introspection tools such as vector top and vector tap connect through this API to show throughput per component. In recent Vector releases the introspection API moved to gRPC, so use a matching Vector CLI version when running vector top against a remote instance.
9. Backups and version control
Vector's state is its configuration. Keep /etc/vector/vector.yaml and any VRL files under version control and deploy them from your repository rather than editing on the box. Validate every change before restarting:
vector validate /etc/vector/vector.yaml && sudo systemctl restart vectorFor disk-buffered sinks, the buffer directory under /var/lib/vector holds in-flight events; it is transient and does not need backing up, but size it appropriately so a downstream outage does not fill the disk.
10. Upgrades
With the apt repository configured, upgrades are routine:
sudo apt update && sudo apt upgrade vector
sudo systemctl restart vectorRead the release notes first. Vector periodically deprecates sink options and metric names and occasionally makes breaking changes (for example, sink defaults and the observability API transport have changed across recent versions), so review before a major bump and test the config with vector validate.
RamNode platform notes
- RamNode prohibits running mail services. Vector has no SMTP sink and is not a mail transport, so it does not conflict with this policy. If you route Vector-derived alerts to a notification channel, use an external API-based service (for example a webhook or a hosted alerting API) rather than an on-box mail relay.
- On an aggregator, expose only the single source port you actually use, and keep it behind TLS. Everything else, including the API on 8686, should stay bound to localhost.
Troubleshooting
vector validatepasses but no data flows: confirm each sink'sinputsreference the correct upstream component ID. A typo in aninputslist silently drops the connection.- Journal source returns nothing: confirm the
vectoruser is in thesystemd-journalgroup and the service was restarted. - Agent cannot connect to the aggregator: confirm the aggregator's firewall allows the source port, that TLS certificate hostnames match, and that
verify_certificateexpectations line up on both ends. - High memory use on the aggregator: review buffer settings and consider enabling disk buffers for high-volume sinks, and confirm transforms are not accidentally duplicating events.
Inspect logs with:
journalctl -u vector -f