This page is for operators who need to start, stop, inspect, or troubleshoot Via services after installation. For the basic setup path, use 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.
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.
via status
via doctor
Expected healthy state:
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.
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.
The builder service handles queued deploy work:
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.
The runner service handles deploy-ready work:
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.
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:
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.
Before a project can deploy, the server needs an app record and managed source repository:
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.
Via reports app deploy state with these terms:
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 for the main reading path.