> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pullbase.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Operations

> Deploy, configure, and troubleshoot the Pullbase agent on your servers.

The Pullbase agent enforces desired state on each managed server. It runs as a native binary managed by systemd — the recommended approach for VMs and bare-metal hosts.

## Deployment methods

### One-liner install script (recommended)

The fastest way to deploy an agent is using the install script endpoint. After registering a server in Pullbase, run:

```bash theme={null}
curl -fsSL "https://pullbase.example.com/api/v1/servers/web-01/install-script?token=pbt_xxx" | sudo bash
```

The script:

* Downloads the agent binary from GitHub releases
* Creates a dedicated `pullbase` service user with security restrictions
* Configures `/etc/pullbase/agent.env` with your server URL and token
* Installs a hardened systemd service
* Starts the agent immediately

<Tip>
  Generate the install command from the UI: navigate to **Servers → \[your server] → Install** to get a ready-to-run curl command with the token pre-filled.
</Tip>

**Optional parameters:**

| Parameter | Description                                                  |
| --------- | ------------------------------------------------------------ |
| `version` | Specific agent version (e.g., `v1.0.0`). Defaults to latest. |
| `ca_cert` | Base64-encoded CA certificate for custom TLS.                |

```bash theme={null}
# Install specific version with custom CA
curl -fsSL "https://pullbase.example.com/api/v1/servers/web-01/install-script?token=pbt_xxx&version=v1.2.0&ca_cert=$(base64 -w0 ca.crt)" | sudo bash
```

### Manual systemd setup

If you prefer manual control or need to customize the installation:

<Steps>
  <Step title="Download the agent binary">
    ```bash theme={null}
    curl -fsSL -o pullbase-agent "https://github.com/pullbase/pullbase/releases/latest/download/pullbase-agent-linux-amd64"
    sudo install -m 0755 pullbase-agent /usr/local/bin/pullbase-agent
    ```
  </Step>

  <Step title="Create environment file">
    ```bash theme={null}
    sudo mkdir -p /etc/pullbase
    sudo tee /etc/pullbase/agent.env > /dev/null <<'EOF'
    SERVER_ID=web-01
    CENTRAL_SERVER_URL=https://pullbase.example.com
    AGENT_TOKEN=pbt_your_token_here
    CACERT_PATH=/etc/pullbase/ca.crt
    SKIP_TLS_VERIFY=false
    EOF
    sudo chmod 600 /etc/pullbase/agent.env
    ```
  </Step>

  <Step title="Create systemd unit">
    ```ini /etc/systemd/system/pullbase-agent.service theme={null}
    [Unit]
    Description=Pullbase Agent
    After=network-online.target
    Wants=network-online.target

    [Service]
    EnvironmentFile=/etc/pullbase/agent.env
    ExecStart=/usr/local/bin/pullbase-agent
    Restart=always
    RestartSec=10
    User=root

    # Security hardening
    NoNewPrivileges=yes
    ProtectSystem=strict
    ProtectHome=yes
    ReadWritePaths=/etc /var

    [Install]
    WantedBy=multi-user.target
    ```
  </Step>

  <Step title="Enable and start">
    ```bash theme={null}
    sudo systemctl daemon-reload
    sudo systemctl enable --now pullbase-agent.service
    sudo systemctl status pullbase-agent.service
    ```
  </Step>
</Steps>

## Environment variables

| Variable             | Required | Default | Description                                                         |
| -------------------- | -------- | ------- | ------------------------------------------------------------------- |
| `SERVER_ID`          | Yes      | -       | Must match the server ID registered in Pullbase                     |
| `CENTRAL_SERVER_URL` | Yes      | -       | Base URL of the Pullbase API (e.g., `https://pullbase.example.com`) |
| `AGENT_TOKEN`        | Yes      | -       | Token provided when the server is created. Rotate regularly.        |
| `CACERT_PATH`        | No       | -       | Path to CA bundle that trusts the Pullbase certificate              |
| `SKIP_TLS_VERIFY`    | No       | `false` | Set to `true` only for development with self-signed certificates    |
| `AGENT_DRY_RUN`      | No       | `false` | When `true`, agent reports what would change without applying       |

<Note>
  The agent also supports legacy environment variable names with `PULLBASE_` prefix: `PULLBASE_SERVER_ID`, `PULLBASE_SERVER_URL`, `PULLBASE_AGENT_TOKEN`, `PULLBASE_CACERT_PATH`.
</Note>

### Dry-run mode

Run the agent in dry-run mode to preview changes without applying them:

```bash theme={null}
# Via environment variable
AGENT_DRY_RUN=true pullbase-agent

# Via command-line flag
pullbase-agent --dry-run
```

In dry-run mode, the agent:

* Checks for configuration drift
* Logs what packages, files, and services would change
* Reports status to the server with "Dry-Run:" prefix
* **Does not apply any changes**

This is ideal for testing new configurations or auditing drift before enabling auto-reconcile.

## Supported package managers

The agent auto-detects the host's package manager:

| Package Manager | Distribution                 | Detection                           |
| --------------- | ---------------------------- | ----------------------------------- |
| APK             | Alpine Linux                 | Checks for `apk` command            |
| APT             | Debian, Ubuntu               | Checks for `apt-get` command        |
| DNF             | RHEL 8+, Fedora, Rocky Linux | Checks for `dnf` command            |
| YUM             | RHEL 7, CentOS 7             | Checks for `yum` command (fallback) |

Package states:

* `present`: Install if not present
* `latest`: Install or upgrade to latest available version
* `absent`: Remove if installed

## Supported service managers

The agent auto-detects the init system:

| Service Manager | Init System               | Detection                                        |
| --------------- | ------------------------- | ------------------------------------------------ |
| systemd         | Most modern distributions | Checks for `systemctl` and `/run/systemd/system` |
| supervisor      | Docker, custom setups     | Checks for `supervisorctl`                       |
| OpenRC          | Alpine Linux, Gentoo      | Checks for `rc-service`                          |

Override detection by setting `system.serviceManager` in `config.yaml`:

```yaml theme={null}
system:
  serviceManager: supervisor
  containerized: true
```

## Reconciliation cycle

<Steps>
  <Step title="Fetch configuration">
    Agent authenticates with its token and calls `GET /api/v1/agent/serverinfo` to obtain Git metadata and the target commit hash.
  </Step>

  <Step title="Obtain Git credentials">
    If the environment uses a GitHub App, agent invokes `GET /api/v1/agent/git-token` to retrieve a short-lived installation token.
  </Step>

  <Step title="Clone or update repository">
    Repository is cloned into `/etc/pullbase/repo`. The agent checks out the target commit.
  </Step>

  <Step title="Apply desired state">
    Packages, services, and files from `config.yaml` are reconciled using the detected package and service managers.
  </Step>

  <Step title="Report status">
    Agent posts results (status, drift, error message) to `PUT /api/v1/agent/status`.
  </Step>
</Steps>

## Drift detection and auto-reconciliation

The agent performs drift checks every 60 seconds and compares:

* Package installation state
* Service running/enabled state
* File content (SHA256 hash) and permissions

When drift is detected and auto-reconcile is enabled for the server's environment, the agent automatically applies the configuration to restore desired state.

## Logging

View agent logs using journalctl:

```bash theme={null}
# Follow logs in real-time
journalctl -u pullbase-agent -f

# Last 100 lines
journalctl -u pullbase-agent -n 100

# Since last boot
journalctl -u pullbase-agent -b
```

The agent logs reconciliation details including:

* Package installation/removal operations
* Service start/stop/enable/disable operations
* File writes and permission changes
* Drift detection results
* Git clone/pull operations

## Troubleshooting

<AccordionGroup>
  <Accordion title="401 Unauthorized">
    * Token revoked or expired → create a new token and update `/etc/pullbase/agent.env`
    * Server ID mismatch → ensure `SERVER_ID` matches the registered server
    * Clock skew → ensure NTP is running; JWT validation is time-based
  </Accordion>

  <Accordion title="Git clone failures">
    * Check network reachability to GitHub (proxy, firewall)
    * For private repos, confirm the GitHub App installation and permissions
    * Validate `CACERT_PATH` so TLS trust is correct
  </Accordion>

  <Accordion title="Package manager errors">
    * Ensure the package manager is available and in PATH
    * Check that package repositories are configured and reachable
    * Verify the agent runs as root (required for package management)
  </Accordion>

  <Accordion title="Service manager not detected">
    * Override auto-detection by setting `system.serviceManager` in `config.yaml`
    * Ensure the service manager commands (`systemctl`, `supervisorctl`, `rc-service`) are in PATH
    * For systemd, verify `/run/systemd/system` exists
  </Accordion>

  <Accordion title="File permission issues">
    * Specify `mode` in `config.yaml` (e.g., `"0644"`)
    * Confirm the agent runs as root (required to manage system files)
    * Check SELinux/AppArmor policies if files are created but inaccessible
  </Accordion>

  <Accordion title="Agent not reporting status">
    * Check connectivity: `curl -I https://pullbase.example.com/api/v1/healthz`
    * Verify token is active in the Pullbase UI
    * Check agent logs for authentication errors
  </Accordion>
</AccordionGroup>

## Upgrading the agent

To upgrade an agent to a newer version:

```bash theme={null}
# Stop the agent
sudo systemctl stop pullbase-agent

# Download new version
curl -fsSL -o /tmp/pullbase-agent "https://github.com/pullbase/pullbase/releases/latest/download/pullbase-agent-linux-amd64"
sudo install -m 0755 /tmp/pullbase-agent /usr/local/bin/pullbase-agent

# Start the agent
sudo systemctl start pullbase-agent

# Verify version in logs
journalctl -u pullbase-agent -n 5
```

Or re-run the install script — it handles upgrades automatically.

## Uninstalling the agent

```bash theme={null}
sudo systemctl stop pullbase-agent
sudo systemctl disable pullbase-agent
sudo rm /etc/systemd/system/pullbase-agent.service
sudo systemctl daemon-reload
sudo rm /usr/local/bin/pullbase-agent
sudo rm -rf /etc/pullbase
```
