
<div class="callout callout-attn"><p><strong>Alpha.</strong> VIA is under active development. APIs, operational flows, and host requirements may change between releases.</p></div>

This page is for operators who need to start, stop, inspect, or troubleshoot Via services after installation. For the basic setup path, use [Install](/docs/via/install/).

Operator examples assume `via install` has added your host user to the Via
admin/shared group. Reconnect or run `newgrp vary` after first install so the
membership is active in your shell.

## Services

Install writes the Via systemd units:

| Unit | Runs as | Responsibility |
|---|---|---|
| `via-server.service` | `via-server` | Serves the control plane, auth, health endpoint, and Git HTTP frontend. |
| `via-builder.service` | `via-builder` | Runs app builds and records build results. |
| `via-runner.service` | `via-runner` | Verifies signed artifacts and supervises runtime containers. |
| `via-test-runner.service` | `via-builder` | Runs server-side test work. |
| `via-config.service` | `via-server` | Serves runtime config, secrets, and add-on descriptors to workloads. |
| Managed proxy service | `via-server` | Publishes validated public routes. |

The Via units read `/etc/via/server.toml` and are managed by systemd.

## Verify the units

```bash
via status
via doctor
```

Expected healthy state:

```bash
via status
```

`via init` starts the services after writing config, keys, and the control-plane database. You want each Via service to report `active`. A restart loop usually means config load failed, the port is already bound, identity material was never initialized, or Docker is unavailable to the worker services.

## Control-plane service

The control-plane service handles the operator and app-owner API surface:

| Responsibility | Detail |
|---|---|
| Health surface | Serves `/health` |
| Identity discovery | Serves `/.well-known/vary/jwks.json` |
| Git frontend | Mounts `/git/<app>.git/...` |

If config is invalid or the port cannot be bound, the command exits non-zero with a single clear stderr line instead of crash-looping noisily under systemd.

## Builder service

The builder service handles queued deploy work:

```mermaid
flowchart TB
    QUEUED[queued] --> BUILDING[building]
    BUILDING --> TYPECHECKING[typechecking]
    TYPECHECKING --> TESTING[testing]
    TESTING --> ARTIFACT[artifact_ready]
```

For successful builds, it records signed-artifact metadata in the control plane. For failed builds, it records the failed phase and reason, and it leaves the current running deploy untouched. That last rule is the main safety property for the failure path.

## Runner service

The runner service handles deploy-ready work:

```mermaid
flowchart TB
    ARTIFACT[artifact_ready] --> DEPLOYING[deploying]
    DEPLOYING --> RUNNING[running]
```

Before launching anything it verifies the signed artifact bundle. Invalid or unsigned artifacts fail closed and never start a container. On success it records runtime state so `vary app status` and `vary app logs` can read it later.

## Structured logging

Every daemon writes JSON Lines to both `journalctl` and a file under `/var/log/via/`:

| Path | Producer |
|---|---|
| `/var/log/via/server.log` | `via start` |
| `/var/log/via/builder.log` | `via builder` |
| `/var/log/via/runner.log` | `via runner` |
| `/var/log/via/test-runner.log` | `via test-runner` |
| `/var/log/via/config-server.log` | `via config-server` |

Useful operator checks:

```bash
journalctl -u via-server -u via-builder -u via-runner -u via-test-runner -u via-config -n 200 --no-pager
tail -n 50 /var/log/via/server.log
```

When troubleshooting, capture a multi-unit journal tail before restarting services so the original failure state is preserved.

## Provision an app

Before a project can deploy, the server needs an app record and managed source repository:

```bash
via app ensure <app-name> --owner <your-name>
```

First call effects:

| Effect | Result |
|---|---|
| App registration | Creates the app record. |
| Source repository | Creates the managed source repository. |
| Deploy intake | Installs the managed hook used when app owners deploy. |

Subsequent calls with the same `(app-name, owner)` pair are a silent no-op. A different owner is an error, not an implicit re-home.

Use `ensure` for repeated setup because it is safe to re-run against an already-provisioned host.

## App state

Via reports app deploy state with these terms:

```text
created
queued
building
typechecking
testing
artifact_ready
deploying
running
failed
cancelled
superseded
```

Every state transition is recorded so operators can inspect what happened to a deploy after source was pushed.

Return to the [Via overview](/docs/via/) for the main reading path.
