Observability
    Logs & Metrics

    Deploy Vector on a VPS

    Run Vector — the high-performance Rust observability pipeline — on a RamNode VPS as an agent or aggregator, with TLS, systemd hardening, and durable buffering.

    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:

    shell
    adduser deploy
    usermod -aG sudo deploy
    rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

    Harden 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.

    shell
    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 enable

    2. Install Vector

    The install script adds the correct package repository for your distribution and installs the latest release, which also creates a systemd unit.

    shell
    curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev | bash

    Alternatively, add the apt repository directly for repeatable, apt-managed upgrades:

    shell
    bash -c "$(curl -L https://setup.vector.dev)"
    sudo apt update
    sudo apt install -y vector

    Confirm the install:

    shell
    vector --version

    The 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:

    shell
    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: json

    Validate the config, then run it in the foreground:

    shell
    vector validate /etc/vector/vector.yaml
    vector --config /etc/vector/vector.yaml

    You 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.

    shell
    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: true

    5. 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.

    shell
    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: json

    Vector 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:

    shell
    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/*.pem

    Add a renewal deploy hook at /etc/letsencrypt/renewal-hooks/deploy/vector.sh:

    shell
    #!/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 vector
    shell
    sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/vector.sh

    7. Run Vector as a service

    The package ships a systemd unit. Enable and start it:

    shell
    sudo systemctl enable --now vector
    sudo systemctl status vector

    Vector runs as the unprivileged vector user by default. For an agent reading the journal, that user must be in the systemd-journal group:

    shell
    sudo usermod -aG systemd-journal vector
    sudo systemctl restart vector

    For 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:

    shell
    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:

    shell
    vector validate /etc/vector/vector.yaml && sudo systemctl restart vector

    For 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:

    shell
    sudo apt update && sudo apt upgrade vector
    sudo systemctl restart vector

    Read 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 validate passes but no data flows: confirm each sink's inputs reference the correct upstream component ID. A typo in an inputs list silently drops the connection.
    • Journal source returns nothing: confirm the vector user is in the systemd-journal group 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_certificate expectations 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:

    shell
    journalctl -u vector -f