Servers

The fleet: enrolling and removing machines, their role, teams and settings, health checks, maintenance and host certificates.

A server is a machine running the Deplo agent. Servers are the one resource shared across teams, so most writes here are instance admin.

Enrolling an ordinary server is a two-step flow: addServer returns an install command, and the host calls home when the command has run. Removing one is trust revocation: removeServer forgets the row and stops trusting the agent, without touching the host. uninstallServerAgent goes further and is only for a migration source.

A server's role is everything, build, storage or import. The install command is the only way into or out of import.

Reading

servers

Any signed-in principal. Returns [Server!].

All servers, by creation order.

query {
  servers {
    id
    name
    host
    role
    status
    agentVersion
  }
}

server

Any signed-in principal. Returns Server.

One server by id, or null.

ArgumentTypeDescription
idString!
query {
  server(id: "srv_9f1c2ab7d3e4f5a6") {
    id
    name
    host
    role
    status
    agentVersion
  }
}

primaryServer

Any signed-in principal. Returns Server.

The first server available, or null when none has been added/provisioned yet.

query {
  primaryServer {
    id
    name
    host
    role
    status
    agentVersion
  }
}

serverWorkloads

Instance admin only. Returns [ServerWorkload!].

Every team's apps and databases on one server, with live status and usage. Instance admins only.

ArgumentTypeDescription
idString!
query {
  serverWorkloads(id: "srv_9f1c2ab7d3e4f5a6") {
    id
    name
    status
    cpu
  }
}

Enrolling and removing

addServer

Instance admin only. Returns AddServerPayload.

Enrol a machine. Returns the install command to paste on the host; the row stays provisioning until the agent calls home. importOnly registers a migration source instead (instance admin).

ArgumentTypeDescription
inputAddServerInput!
input.allTeamsBoolean
input.buildOnlyBoolean
input.hostString!
input.importOnlyBoolean
input.nameString!
input.storageOnlyBoolean
input.teamIds[String!]
mutation {
  addServer(
    input: { name: "eu-1", host: "203.0.113.10", allTeams: true }
  ) {
    installCommand
    server {
      id
      name
      status
    }
  }
}

reissueServerBootstrap

Instance admin only. Returns AddServerPayload.

Mint a fresh install command for a server still provisioning (the original token expired or was lost).

ArgumentTypeDescription
idString!
mutation {
  reissueServerBootstrap(id: "srv_9f1c2ab7d3e4f5a6") {
    installCommand
    server {
      id
      name
      status
    }
  }
}

removeServer

Instance admin only. Returns ServerRemoval.

Remove a server: revoke its agent's trust and forget the row. This does NOT uninstall anything on the host (the agent, Traefik and the Deplo network keep running there), so the returned payload always carries the host-side uninstall command. Blocked while any App or database still lives on the server.

ArgumentTypeDescription
idString!
mutation {
  removeServer(id: "srv_9f1c2ab7d3e4f5a6") {
    uninstallCommand
    warning
  }
}

uninstallServerAgent

Instance admin only. Returns ServerUninstall.

Take Deplo off a MIGRATION SOURCE: uninstall the agent from the host (systemd unit, binary, state dir - never Docker), then forget the server. Only a server whose role is "import" - an ordinary server is removed with removeServer, which is trust revocation and leaves the host alone. removed: false means the host still has the agent on it and the server row was KEPT; uninstallCommand is returned either way, because an unreachable or de-trusted host will always need the host-side path. A registration whose install command was never run has nothing to uninstall and is simply forgotten.

ArgumentTypeDescription
idString!
mutation {
  uninstallServerAgent(id: "srv_9f1c2ab7d3e4f5a6") {
    removed
    uninstallCommand
  }
}

agentUninstallCommand

Any signed-in principal. Returns String.

The paste-on-the-host command that removes Deplo's agent from a machine. Instance-wide, identical for every host, and carrying no secret - the installer it points at is served unauthenticated by design. Shown next to a migration source Deplo could not reach, because an unreachable host's agent can only be taken off from the host.

query {
  agentUninstallCommand
}

Settings

renameServer

Instance admin only. Returns Server.

Change a server's display name. Cosmetic: nothing dials, routes or deploys by name.

ArgumentTypeDescription
idString!
nameString!
mutation {
  renameServer(id: "srv_9f1c2ab7d3e4f5a6", name: "shop") {
    id
    name
    host
    role
    status
    agentVersion
  }
}

setServerRole

Instance admin only. Returns Server.

Change what a server is for: "everything", "build" or "storage". Leaving "everything" is refused while the host still has apps or databases on it. A server INSTALLED as backups-only has no Docker and stays pinned to "storage" until its install command is re-run on the host. "import" is not settable and a migration source is not convertible: the install command is the way in and the way out.

ArgumentTypeDescription
idString!
roleString!
mutation {
  setServerRole(id: "srv_9f1c2ab7d3e4f5a6", role: "build") {
    id
    role
  }
}

setServerTeams

Instance admin only. Returns Server.

Set a server's team access. allTeams: true makes it available to every team; false restricts it to teamIds. Blocked (clear error) when a team that still has apps or databases on the server would lose access.

ArgumentTypeDescription
inputSetServerTeamsInput!
input.allTeamsBoolean!
input.serverIdString!
input.teamIds[String!]
mutation {
  setServerTeams(
    input: { serverId: "srv_9f1c2ab7d3e4f5a6", allTeams: false, teamIds: ["team_9f1c2ab7d3e4f5a6"] }
  ) {
    id
    name
    host
    role
    status
    agentVersion
  }
}

setServerBuildFallback

Instance admin only. Returns Server.

Whether this host may compile for an app whose own build server could not be reached (the app's own server stays the last resort). Omit the flag to go back to automatic: the Deplo host builds as a fallback, no other server does. Refused on a host with no Docker of ours to build with.

ArgumentTypeDescription
buildFallbackBoolean
idString!
mutation {
  setServerBuildFallback(id: "srv_9f1c2ab7d3e4f5a6", buildFallback: true) {
    id
    buildFallback
  }
}

setServerDeployConcurrency

Instance admin only. Returns Server.

Set how many deployments this server runs at once (the per-server slot count the deploy queue enforces). 1 = strict serialization. Whole number in [1, 50].

ArgumentTypeDescription
concurrencyInt!
idString!
mutation {
  setServerDeployConcurrency(concurrency: 2, id: "srv_9f1c2ab7d3e4f5a6") {
    id
    name
    host
    role
    status
    agentVersion
  }
}

setServerTimezone

Instance admin only. Returns ServerHostInfo.

Set the host clock's timezone to an IANA zone name (e.g. "Europe/Rome"). Changes the wall-clock LABEL, not the instant: nothing restarts, and Deplo's own schedules (backups, cleanup) stay on UTC. Aliases are accepted and canonicalised ("US/Eastern" is stored as "America/New_York"); a bare UTC offset is not a zone and is refused. Returns a fresh reading of the host, so the moved clock is visible without a second call. The agent rejects a zone the host does not carry.

ArgumentTypeDescription
idString!
timezoneString!
mutation {
  setServerTimezone(id: "srv_9f1c2ab7d3e4f5a6", timezone: "Europe/Rome") {
    timezone
    utcOffsetMinutes
  }
}

updateServerAddress

Instance admin only. Returns String.

Rewrite where Deplo dials this server's agent - the migration verb for a host whose IP changed. Unless force, the agent must answer at the new address (same pinned certificate) before anything is saved. Returns a warning to surface, or null.

ArgumentTypeDescription
addressString!
agentPortInt
forceBoolean
idString!
keepHostBooleanWrite only where Deplo dials, keeping the address the server was registered at. The migration wizard's flag: a panel behind a proxy hands out the proxy's address, and the import still has to recognise the machine by the one it came from.
mutation {
  updateServerAddress(id: "srv_9f1c2ab7d3e4f5a6", address: "203.0.113.20")
}

Health and readiness

checkServerHealth

Instance admin only. Returns Server.

Probe ONE server's agent right now (a live Hello) and persist what it reports: online, warning (agent up, Docker unreachable), error (agent untrusted or broken) or offline. Returns the refreshed server. Throttled server-side even when forced, so it cannot be used to hammer a host; an inconclusive probe leaves the previous observation untouched rather than guessing.

ArgumentTypeDescription
forceBooleanBypass the ambient throttle (the operator asked for this check explicitly). A short floor still applies.
idString!
mutation {
  checkServerHealth(id: "srv_9f1c2ab7d3e4f5a6", force: true) {
    id
    status
    statusMessage
  }
}

checkAllServerHealth

Instance admin only. Returns [Server!].

Probe every provisioned server's agent and persist each outcome; returns every server (unprovisioned ones pass through untouched). This is what the Servers page runs on load, so a reload always reflects reality rather than the status a server had when it first called home.

ArgumentTypeDescription
forceBooleanBypass the ambient throttle (the header's 'Check all' button).
mutation {
  checkAllServerHealth {
    id
    name
    status
  }
}

checkServerHostInfo

Instance admin only. Returns ServerHostInfo.

Read what this server IS, right now: CPU model and core count, installed RAM, disk, distribution, kernel, architecture, Docker version and data root, uptime, and the host's own clock and timezone. Also reports whether Deplo manages the Traefik here and whether the Deplo panel runs in a container the agent could restart. Persists nothing. Errors clearly when the agent is unreachable or too old for host management.

ArgumentTypeDescription
idString!
mutation {
  checkServerHostInfo(id: "srv_9f1c2ab7d3e4f5a6") {
    osPretty
    kernel
    arch
    cpuCores
    timezone
  }
}

checkServerReadiness

Instance admin only. Returns ServerReadinessReport.

Check whether ONE server's installation is complete enough to run deployments, right now. Dials the agent (Hello), bind-tests host ports 80 and 443, and reads host metrics, then reports what it found: the agent's handshake/protocol/version and which build methods and platform features it supports, whether Docker answers, whether a Traefik container is running and holds the web ports, disk headroom, and this server's team access and deploy concurrency. Never persisted - it does not touch status, so it can neither create nor cure a stale badge. Degrades honestly: an agent too old to bind-test ports reports those rows as skipped, never as a pass.

ArgumentTypeDescription
idString!
mutation {
  checkServerReadiness(id: "srv_9f1c2ab7d3e4f5a6") {
    verdict
    summary
    checks {
      label
      severity
    }
  }
}

Maintenance

retryServerAgentUpdate

Instance admin only. Returns ServerAgentUpdate.

Try again, now, to update this server's agent to the version this Deplo is pinned to. Only after Deplo's own attempt failed: it cancels the scheduled retry, keeps the 24-hour window running, and is refused while another attempt is in progress. Returns the attempt as it starts; poll server(id).agentUpdate for the outcome.

ArgumentTypeDescription
idString!
mutation {
  retryServerAgentUpdate(id: "srv_9f1c2ab7d3e4f5a6") {
    attempts
    failed
    failure
    firstFailedAt
  }
}

fleetAgents

Instance admin only. Returns FleetAgents.

The fleet's agent versions, and whether Deplo is still rolling an update out to them.

query {
  fleetAgents {
    expected
    minimum
    pausedBy
    total
  }
}

restartServerTraefik

Instance admin only. Returns Boolean.

Restart the Traefik reverse proxy on this server. The configuration is untouched - this is the 'it is wedged, bounce it' action. Routing on this host is interrupted for the few seconds Traefik takes to come back. Errors when Deplo did not install Traefik there.

ArgumentTypeDescription
idString!
mutation {
  restartServerTraefik(id: "srv_9f1c2ab7d3e4f5a6")
}

restartServerWorkloads

Instance admin only. Returns ServerRestartReport.

Restart every App and database Deplo runs on this server, one at a time. Containers Deplo did not deploy are never touched. Workloads that are already stopped are skipped rather than started (restarting and starting are different actions), as are workloads with a deploy in flight, which come back on their own. An App whose last deploy FAILED is restarted, not skipped: a failed deploy usually leaves the previous stack serving. Reports per-workload failures instead of stopping at the first one, and says explicitly when a workload stopped but did not start again.

ArgumentTypeDescription
idString!
mutation {
  restartServerWorkloads(id: "srv_9f1c2ab7d3e4f5a6") {
    restarted
    skipped
    failures {
      name
      error
    }
  }
}

restartDeploPanel

Instance admin only. Returns Boolean.

Restart the Deplo control plane on the host that runs it. Refused for any other server. Returns once the restart is SCHEDULED, not once it is done: the restart ends the process serving this request, so the answer necessarily arrives first - expect the dashboard to be briefly unreachable.

ArgumentTypeDescription
idString!
mutation {
  restartDeploPanel(id: "srv_9f1c2ab7d3e4f5a6")
}

retryNetworkIsolation

Instance admin only. Returns Boolean.

Run the network-isolation move again for every stack it could not reach the first time. Each app and database is brought up on the network its environment owns, one host at a time; one that still cannot be reached stays where it is and is reported in Activity. Safe to run more than once - a stack already on the right network is a no-op.

mutation {
  retryNetworkIsolation
}

dismissNetworkIsolationNotice

Instance admin only. Returns Boolean.

Put the Overview's network-isolation notice away for good. It reports how many stacks the one-time move could not reach; the stacks themselves are untouched and each one still moves on its next deploy. retryNetworkIsolation brings the notice back if a stack still cannot be reached.

mutation {
  dismissNetworkIsolationNotice
}

Certificates

A host's own TLS certificates, installed by hand outside Let's Encrypt. They live in that host's proxy, Deplo keeps no copy, and the private key is write-only. A domain uses one by setting certProvider: custom. The Let's Encrypt account email is per host too. All of these are mutations even where they only read, because they dial a server.

serverCertificates

Instance admin only. Returns [ServerCertificate!].

List the TLS certificates installed on this server by hand, read live from its proxy. Deplo keeps no copy of them, so this is what the host is actually serving. Errors when Deplo did not install the proxy there.

ArgumentTypeDescription
idString!
mutation {
  serverCertificates(id: "srv_9f1c2ab7d3e4f5a6") {
    id
    subject
    domains
    expiresInDays
  }
}

addServerCertificate

Instance admin only. Returns [ServerCertificate!].

Install a TLS certificate on this server. The certificate and its key are checked as a pair before the host is touched: a key that does not match, or a certificate that has already expired, is refused. The proxy then serves it for every domain named in it, taking precedence over Let's Encrypt, which stops issuing for domains a certificate already covers. Uploading one for the same domains replaces it. Applying recreates the proxy, so routing on this host is interrupted for a few seconds. Returns the certificates installed afterwards.

ArgumentTypeDescription
idString!
inputServerCertificateInput!
input.certificateString!The certificate in PEM form. Paste the FULL chain: the certificate followed by any intermediates, which browsers need.
input.privateKeyString!The matching private key in PEM form, without a passphrase. It is sent to the server and is never readable afterwards.
mutation {
  addServerCertificate(
    id: "srv_9f1c2ab7d3e4f5a6"
    input: { certificate: "-----BEGIN CERTIFICATE-----\n…", privateKey: "-----BEGIN PRIVATE KEY-----\n…" }
  ) {
    id
    subject
    domains
    expiresInDays
  }
}

removeServerCertificate

Instance admin only. Returns [ServerCertificate!].

Remove a certificate from this server by its fingerprint. Its domains fall back to whatever else covers them, usually Let's Encrypt, which issues for them again once the proxy comes back. Recreates the proxy, so routing on this host blips.

ArgumentTypeDescription
certificateIdString!
idString!
mutation {
  removeServerCertificate(certificateId: "sha256:3f8c…", id: "srv_9f1c2ab7d3e4f5a6") {
    id
    subject
    domains
    expiresInDays
  }
}

serverCertificateAccounts

Instance admin only. Returns [CertificateAccount!].

Read the Let's Encrypt account email off every server's proxy, live. Per host, because the address is a flag in each host's own stack file and a fleet installed over time can genuinely disagree with itself. A host Deplo cannot manage reports why instead of an address.

mutation {
  serverCertificateAccounts {
    serverName
    email
    unavailable
  }
}

setCertificateEmail

Instance admin only. Returns [CertificateAccount!].

Point every manageable server's certificates at this account email, where Let's Encrypt sends expiry and revocation notices. Each host's proxy is recreated to pick it up, one host at a time, so routing there is interrupted for a few seconds; certificates already issued keep working. Servers Deplo cannot manage are skipped and reported as skipped, never counted as done.

ArgumentTypeDescription
emailString!
mutation {
  setCertificateEmail(email: "[email protected]") {
    serverName
    email
    unavailable
  }
}

See also

Did this page help you?

On this page