Instance settings

The panel's own address and HTTPS, instance-wide switches, updates and instance ownership.

The panel publishes itself through its host's proxy, so the address it answers on is a setting, not an install-time fact. setPanelUrl moves the route with the address and puts the old one back if the new address does not answer. instanceSettings.panelIpUrl is the address every instance also answers on straight on its own machine: not a setting, cannot be turned off, and the way back in when a domain or certificate broke.

Moving the address or dropping HTTPS breaks things a text field does not show: passkeys welded to the current hostname, live sessions, deploy hooks pasted into CI, connected AI clients. panelAddressImpact counts what a given address would cost. Read it before you write.

Settings

instanceSettings

Instance admin only. Returns InstanceSettings.

This instance's own settings. A plain database read: it never dials a server, so it answers even when the fleet is down.

query {
  instanceSettings {
    panelUrl
    panelUrlSource
    gravatarEnabled
    logMaxDays
    version
  }
}

setGravatarEnabled

Instance admin only. Returns InstanceSettings.

Turn Gravatar profile pictures on or off for the whole instance. On, a person with no uploaded picture falls back to the one registered against their address, and each VIEWER's browser fetches it - the panel itself never dials out, so an instance with no egress still works. Off, no Gravatar address is emitted anywhere and nothing about anybody leaves the instance. Instance-wide because it is a property of this deployment's egress and policy, not of one team's taste.

ArgumentTypeDescription
enabledBoolean!
mutation {
  setGravatarEnabled(enabled: true) {
    panelUrl
    panelUrlSource
    gravatarEnabled
    logMaxDays
    version
  }
}

setLogMaxDays

Instance admin only. Returns InstanceSettings.

Set how far back the log viewer's time range may reach, in days. It is a ceiling on the ranges the picker offers, not a retention policy: docker rotates a container's logs by SIZE, so nothing here makes a host hold more of them, and a window that comes back empty says the host rotated them rather than pretending the app was quiet. Clamped rather than rejected - the field is a number input with the same bounds, so a value outside them arrived from an API client, and the honest answer to "keep 900 days" is the ceiling.

ArgumentTypeDescription
daysInt!
mutation {
  setLogMaxDays(days: 30) {
    panelUrl
    panelUrlSource
    gravatarEnabled
    logMaxDays
    version
  }
}

welcomeSeen

Any signed-in principal. Returns Boolean.

Mark the first-run welcome as shown, so it opens exactly once in an instance's life. Stamped on the singleton settings row rather than in the browser, because the wizard's ?welcome=1 is lost on a reload and a second browser would otherwise replay the celebration. Only the instance owner writes it; anybody else is a no-op, and so is a second call.

mutation {
  welcomeSeen
}

finishSetup

Any signed-in principal. Returns AuthPayload.

Finish an account the installer created with a temporary password: profile, new password, team. Signs in again.

ArgumentTypeDescription
imageString
nameString!
passwordString!
teamImageString
teamNameString!
usernameString
mutation {
  finishSetup(
    name: "shop"
    password: "correct-horse-battery-staple"
    teamName: "Acme"
  ) {
    requiresTwoFactor
    viewer {
      id
      username
    }
  }
}

Panel address and HTTPS

panelAddressImpact

Instance admin only. Returns PanelAddressImpact.

What moving the panel to this address would break: passkeys welded to the current hostname, sessions, deploy hooks already pasted into someone's CI, connected AI clients, invite links, servers still waiting for their install command, notification subscriptions. Counted live and instance-wide, and only meaningful when the address actually moves - an unchanged address answers all zeroes. A query, not a mutation: it reads the database and dials nothing.

ArgumentTypeDescription
urlString!
query {
  panelAddressImpact(url: "https://deplo.example.com") {
    sessions
    passkeys
    deployHooks
    mcpConnections
    losesHttps
  }
}

setPanelUrl

Instance admin only. Returns InstanceSettings.

Set the address this Deplo answers on, or pass no url to fall back to DEPLO_PUBLIC_URL. A bare domain becomes https://. The value is validated as a hostname with no path, no credentials and no shell metacharacters, because it is interpolated into copy-and-run strings such as a server's install command. On a Deplo that publishes itself through its own proxy this MOVES the panel's route too, and puts the old one back if the new address does not answer; DNS still has to point at the server first.

ArgumentTypeDescription
urlString
mutation {
  setPanelUrl(url: "https://deplo.example.com") {
    panelUrl
    panelUrlSource
  }
}

panelDns

Instance admin only. Returns PanelDns.

Resolve the panel's own hostname and classify it the way a custom domain is classified: valid when its A or AAAA records point at this host and none points elsewhere, cloudflare when they are Cloudflare's anycast addresses and the origin cannot be read from DNS, misconfigured when it answers with something else, pending when it does not resolve, and unknown when there is nothing to check (a bare IP, or no host address on record). A mutation despite writing nothing, for the same reason panelHttps is one: it leaves the process.

mutation {
  panelDns {
    host
    status
    resolved
  }
}

panelHttps

Instance admin only. Returns PanelHttps.

Read how the panel is served off the proxy that publishes it, live. A mutation despite writing nothing, for the same reason serverCertificateAccounts is one: it dials a server.

mutation {
  panelHttps {
    enabled
    domain
    certificateTrusted
  }
}

setPanelHttps

Instance admin only. Returns PanelHttps.

Serve the panel over https, or over plain http. Turning it off is for a panel whose address cannot get a certificate - it does not resolve publicly yet, :80 is closed, the box is internal - where https means a browser warning on a page nobody has logged into yet. Three things move together: the route goes to the :80 entrypoint (with that entrypoint's redirect pinned below it), the stored panel address takes the new scheme, and the session cookie drops its __Secure- prefix, without which the panel would load over http and be impossible to log into. The host's proxy is recreated to pick it up, so sites on that server - this panel included - are unreachable for the few seconds it takes to come back. On a Deplo installed before it published its own route, the first change ADOPTS that route: Deplo writes one beside the container labels the installer left and outranks them, after proving from inside the network that it knows where the panel listens.

ArgumentTypeDescription
enabledBoolean!
mutation {
  setPanelHttps(enabled: false) {
    enabled
    domain
  }
}

setPanelFallback

Instance admin only. Returns InstanceSettings.

Turn the generated deplo-<hexip>.deplo.site backup route on or off. Off drops the second router from the panel's own Traefik file and remembers the choice, so moving the address or the scheme afterwards does not put it back - which is the whole reason this is stored rather than read off the host. The panel then answers on its domain and nowhere else: if that domain, its DNS or its certificate breaks, the way back in is deplo recover panel-address on the server. Refused while the generated address IS the panel's own address, which would leave no route at all.

ArgumentTypeDescription
enabledBoolean!
mutation {
  setPanelFallback(enabled: true) {
    panelUrl
    panelUrlSource
    gravatarEnabled
    logMaxDays
    version
  }
}

Updates

updateInfo

Instance admin only. Returns UpdateInfo.

Check the upstream repository for a newer Deplo release; cached for an hour.

query {
  updateInfo {
    current
    latest
    updateAvailable
  }
}

deploChangelog

Instance admin only. Returns DeploChangelog.

Deplo's published releases with their notes, newest first; canaries only while updateInfo.canary is on (or the one running). Cached for an hour and refreshed by checkForUpdates.

query {
  deploChangelog {
    releases {
      tag
      name
      publishedAt
    }
  }
}

checkForUpdates

Instance admin only. Returns UpdateInfo.

Re-run the upstream release check ignoring the cache, and expire the changelog beside it.

mutation {
  checkForUpdates {
    current
    latest
    updateAvailable
  }
}

updateDeplo

Instance admin only. Returns DeploUpdateStarted.

Update this instance to the newest release: the agent on the machine Deplo runs on re-runs the installer.

mutation {
  updateDeplo {
    logPath
    version
  }
}

setCanaryReleases

Instance admin only. Returns UpdateInfo.

Offer canary (pre-release) versions of Deplo as updates, or go back to stable ones. Server agents follow the agent version the installed Deplo is pinned to, never this switch. Installs nothing: a newer version shows up as an update, and turning it off never downgrades anything already on a canary.

ArgumentTypeDescription
enabledBoolean!
mutation {
  setCanaryReleases(enabled: true) {
    current
    latest
    updateAvailable
  }
}

Usage reports

usageReport

Instance admin only. Returns UsageReportPreview.

See what would be sent: the anonymous Usage report as it stands this second. A plain database read that dials nothing.

query {
  usageReport {
    instanceId
    json
    lastSentAt
  }
}

setUsageReportsEnabled

Instance admin only. Returns InstanceSettings.

Turn anonymous usage statistics on or off for the whole instance. Off takes effect at once - no final report, no goodbye - and clears the instance id, so turning it on again starts a history that cannot be joined to the old one. Recorded in Activity. Has no effect while the install set DO_NOT_TRACK=1.

ArgumentTypeDescription
enabledBoolean!
mutation {
  setUsageReportsEnabled(enabled: true) {
    panelUrl
    panelUrlSource
    gravatarEnabled
    logMaxDays
    version
  }
}

Moving Deplo to another machine

The old Deplo mints a move code with createMoveCode; a fresh Deplo on the new machine connects with it and starts the copy. The calls keyed by the move's id are public on purpose: the copy signs everyone out, so the progress page cannot lean on a session.

deploMoveReadiness

Instance admin only. Returns DeploMoveReadiness.

query {
  deploMoveReadiness {
    ready
    reason
  }
}

sourceMove

Instance admin only. Returns SourceMove.

This Deplo's move to another machine, or null when there is none (an unused code that expired counts as none).

query {
  sourceMove {
    id
    createdAt
    expiresAt
    finishedAt
  }
}

createMoveCode

Instance admin only. Returns MoveCode.

Mint the code that lets a new Deplo copy this one onto its machine. Replaces an unused or finished code; refused while a copy runs.

mutation {
  createMoveCode {
    code
    expiresAt
  }
}

cancelMoveCode

Instance admin only. Returns Boolean.

Withdraw the move code, or stop a copy in progress: every app paused for it starts again here. A finished copy has nothing to cancel.

mutation {
  cancelMoveCode
}

resumeMoveSchedules

Instance admin only. Returns Boolean.

Turn on the cron jobs and backup schedules a Deplo move left paused here, so they never run on both Deplos at once.

mutation {
  resumeMoveSchedules
}

targetMove

Instance admin only. Returns String.

The id of the move into this Deplo that is still open, or null. deploMoveStatus reads it.

query {
  targetMove
}

deploMoveStatus

Public, no authentication. Returns DeploMoveStatus.

Public on purpose: the id is unguessable and the copy signs everyone out, so the progress page cannot lean on a session. Null for an unknown id.

ArgumentTypeDescription
idString!
query {
  deploMoveStatus(id: "id_9f1c2ab7d3e4f5a6") {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

connectDeploMove

Instance admin only. Returns DeploMovePreview.

Reach the old Deplo with its move code and preview the move. Changes nothing on either side; only a fresh Deplo can receive one.

ArgumentTypeDescription
codeString!
urlString!The old Deplo's https address.
mutation {
  connectDeploMove(code: "123456", url: "https://panel.example.com") {
    id
    canStart
    peerUrl
    problems
  }
}

startDeploMove

Instance admin only. Returns DeploMoveStatus.

Start a connected move: everything here is replaced by a copy of the old Deplo, then each app and database is deployed on its mapped server and filled with its data. The old Deplo keeps running.

ArgumentTypeDescription
idString!
map[DeploMoveServerMapInput!]Where each old server lands here. Every one but a migration source needs a server here, and one holding apps or databases needs one that runs apps.
map.fromString!The old Deplo's server id.
map.toStringA server id here, from the preview's choices. Ignored for a migration source.
mutation {
  startDeploMove(id: "id_9f1c2ab7d3e4f5a6") {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

retryDeploMove

Public, no authentication. Returns DeploMoveStatus.

Resume a failed move: the copy again if it never landed, else every app or database not copied yet. Public by the move's unguessable id, like its progress page.

ArgumentTypeDescription
idString!
mutation {
  retryDeploMove(id: "id_9f1c2ab7d3e4f5a6") {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

skipDeploMoveWorkload

Instance admin only. Returns DeploMoveStatus.

Leave out an app or database that failed to copy, so the move can finish without it. It stays in this Deplo, stopped and without its data; once nothing else is left, the move finishes.

ArgumentTypeDescription
idString!
kindDeploMoveWorkloadKind!One of app, database.
workloadIdString!
mutation {
  skipDeploMoveWorkload(
    id: "id_9f1c2ab7d3e4f5a6"
    kind: "app"
    workloadId: "id_9f1c2ab7d3e4f5a6"
  ) {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

finishDeploMoveWithoutSource

Public, no authentication. Returns DeploMoveStatus.

Finish a stopped move when the old Deplo is gone for good: every app or database whose data never came across is left out, not deployed. Refused while the old Deplo answers. For an instance admin only: it runs after the copy landed.

ArgumentTypeDescription
idString!
mutation {
  finishDeploMoveWithoutSource(id: "id_9f1c2ab7d3e4f5a6") {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

cancelDeploMove

Public, no authentication. Returns DeploMoveStatus.

Abandon a move any time before it is done, even while it runs: the old Deplo starts what it paused, what the move deployed here is removed and this Deplo goes back to setup. Public by the move's id until the copy lands; after that, for an instance admin only.

ArgumentTypeDescription
idString!
mutation {
  cancelDeploMove(id: "id_9f1c2ab7d3e4f5a6") {
    id
    createdAt
    canCancel
    canFinishWithoutSource
  }
}

Ownership

The instance owner is the tier above instance admin: the one account that can hand the instance over.

viewerIsInstanceOwner

Any signed-in principal. Returns Boolean.

Whether the viewer owns this instance (the tier above instance admin).

query {
  viewerIsInstanceOwner
}

transferInstanceOwner

Instance admin only. Returns Boolean.

Hand instance ownership to another instance admin. Owner-only; requires the caller's password, plus a two-factor code when their account has 2FA on. Returns true.

ArgumentTypeDescription
codeString
passwordString!
userIdString!
mutation {
  transferInstanceOwner(
    password: "correct-horse-battery-staple"
    userId: "user_9f1c2ab7d3e4f5a6"
  )
}

See also

Did this page help you?

On this page