Gemini CLI + xCloud

Run Docker apps with Gemini CLI on xCloud

Running Docker apps with Gemini CLI means asking Google's terminal agent to scan the Compose file in your repository, create the Docker site on xCloud after you approve a dry run and keep it backed up and recoverable.

  • Skill: xcloud:deploy
  • Toolsets: sites, servers
  • Free with every xCloud account

YouScan the compose file on main and deploy it to the Frankfurt Docker server. Dry run first.

mcp_xcloud_git_compose-scanread-only

Agentdocker-compose.yml: services app and db. app publishes 5000, db publishes nothing. xCloud would proxy to 5000.

mcp_xcloud_servers_sites_git_dockerdry run

AgentDry run resolved: port 5000, no warnings. Create the site on Frankfurt?

YouYes.

mcp_xcloud_servers_sites_git_dockerneeds approval

AgentCreated with the same body and an idempotency key. Provisioning has started on Frankfurt; I am polling the site status and will fetch the URL once it is live.

. Keep a human in the loop: xCloud stops and asks before anything that creates, deploys, updates, reboots, deletes or buys.

Setup

How Do You Set Up Gemini CLI to Run Docker apps on xCloud?

Connect Gemini CLI once; every job on this account uses the same connection. Then ask in plain words.

  1. Add the xCloud MCP server

    Run this in your terminal, then start gemini. The --scope user flag writes the server to ~/.gemini/settings.json so it is available in every project; without it, gemini mcp add writes to the current project's .gemini/settings.json and refuses to run from your home directory. The first time it calls xCloud it finds the OAuth endpoints, opens your browser on the xCloud approval screen and asks you to tick the teams and choose Read-only or Full access.

    Terminal
    gemini mcp add --scope user --transport http xcloud https://app.xcloud.host/mcp
  2. Or edit settings.json

    Add this to ~/.gemini/settings.json for every project, or to .gemini/settings.json in one project. This is the entry gemini mcp add writes: url plus type set to http. The older httpUrl key still works, but a url without a type is treated as an SSE server and will not connect. If the browser sign-in does not start, type /mcp auth xcloud inside Gemini CLI.

    JSON
    {
      "mcpServers": {
        "xcloud": {
          "url": "https://app.xcloud.host/mcp",
          "type": "http"
        }
      }
    }
  3. No browser? Use an API key

    For a headless machine, create a token with the mcp:invoke scope plus the read abilities for the areas it will use (read:servers and read:sites, with read:billing and read:addons for billing and add-on tools) and the matching write: abilities if it should change things in Settings, Developers, API Tokens and send it in the headers field. Keep the token out of version control, and keep the quotes: xCloud tokens contain a pipe character.

    JSON
    {
      "mcpServers": {
        "xcloud": {
          "url": "https://app.xcloud.host/mcp",
          "type": "http",
          "headers": {
            "Authorization": "Bearer YOUR_TOKEN"
          }
        }
      }
    }
  4. Check it worked

    Then ask Gemini CLI for the job itself, for example:

    Prompt
    Scan the compose file on main and list the services and published ports.

In practice

How Does Docker apps Work from Gemini CLI?

Gemini CLI asks before it runs a tool, and in the Docker flow that gives you two confirmations that do different jobs. The first is Gemini CLI's own prompt before it calls an xCloud tool such as mcp_xcloud_git_compose-scan; the second is xCloud's rule that a create without an explicit confirm is refused. Reading a scan is harmless, so you will accept it quickly. The create is where you slow down and read the dry run. The names matter because Gemini CLI prefixes every tool with mcp_ and the server name, so what you see on screen is mcp_xcloud_servers_sites_git_docker for the create and mcp_xcloud_sites_docker_backup for a backup.

In practice you start gemini in the repository and type one line: scan the Compose file and deploy it to the Frankfurt Docker server. Gemini CLI runs git_detect, then git_compose-scan, and reports the services, the published ports and the suggested primary port. If your docker-compose.yml is at the root it uses that file; if the project keeps a compose.yaml or a file in a subdirectory, the scan resolves the path and the create goes through the pinned Docker request with the path the scan returned. The dry run prints the compose file, port, address and warnings, you say yes, and it polls the site status and fetches the URL before it reports success. A 502 sends it back to the Compose file to look for a service that publishes no port.

Because the terminal is where you already run git, the repair loop is short. Gemini CLI can edit the ports mapping to 127.0.0.1 on a high port, you commit and push, and it scans again. For upkeep it takes a Docker backup before an image bump, reads the list with sites_docker_backups and adds a note to the backup with sites_docker_backup_note_update so the reason is recorded. When a deploy fails it reads the diagnosis, shows the settings it would change and retries on the same site, so the domain and port stay put. A restore is left to the dashboard, and Gemini CLI tells you where it is.

Gemini CLI specific: Do not set trust to true on the xcloud entry in settings.json. It makes Gemini CLI skip its own confirmation dialogs, which for a Docker app means the deploy and the backup, which stops the app while it captures, would run with only xCloud's check in front of them. Keep trust off, so every xCloud tool call gets both a Gemini CLI prompt and xCloud's confirmation rule.

What xCloud does for docker apps

xCloud reads the repository, scans the Compose file for services and ports before anything is created, previews the site with a dry run and deploys it behind its own nginx once you approve. Docker sites can be backed up on demand and on a schedule, and a failed deploy is diagnosed and retried on the same site.

  1. Pick a Docker server. The agent uses the server you name, or lists your servers and asks. A Docker deploy needs a Docker server; any other stack answers with an incompatible_server refusal, and an agentic server never takes a second site. WordPress is not supported on Docker servers.
  2. Detect the repository. git_detect reads the repository root for a Dockerfile or one of the four Compose file names, and checks access and server compatibility. It creates nothing, and an access problem is never worked around by naming an app type by hand.
  3. Scan the Compose file. git_compose-scan runs before the dry run. It lists the services and the host ports the file publishes, resolves which Compose file name it found, and suggests a primary port. The agent never guesses the port.
  4. Dry run, then one approval. The agent sends the Docker create request with dry_run set to true and shows the resolved configuration: compose file, port, address and warnings. It asks once, naming the server and the URL, before sending the same body with confirm set to true and an idempotency key.
  5. Poll and verify. A 202 means queued, not running. The agent polls the site status until it is terminal, reads failed_steps and the SSL block, and fetches the URL before it calls the app live. A 502 here usually means the Compose file publishes no port.
  6. Back up and recover. The agent can take a Docker backup, read the backup list and settings, and add a note to a backup. If a deploy fails it reads the diagnosis, proposes a fix from the correctable fields and retries on the same site after your approval. Restoring a backup is a dashboard step.

Reference

Docker apps Settings and Limits on xCloud

The facts Gemini CLI works within when it runs Docker apps. Where a row names the dashboard, that step stays yours to take there.

Setting or limitWhat applies
Supported inputsA Dockerfile for a single container, or a Compose file for one or more services, on a Docker server. Go, Python, Rust and Java apps all deploy this way
Server stackDocker servers only. The Docker deploy on any other stack, including an agentic server, answers 422 with the code incompatible_server
Which Compose file runsdocker-compose.yml at the repository root. A file named compose.yaml, compose.yml or docker-compose.yaml, or one in a subdirectory, deploys through the pinned Docker create with docker.compose_file set to the path the scan resolved
Public portxCloud's nginx owns ports 80 and 443 and proxies to one host port of 1024 or higher on 127.0.0.1. xCloud runs your Compose file as-is and never rewrites its ports mapping
Port refusalsA port another site already holds is refused as port_unavailable. A port the file does not publish is refused as port_not_published, with the published ports listed
No published portA Compose file that publishes no port is accepted and then answers 502, so the scan is the step that catches it
Private registriesThe deploy runs docker compose pull and never docker login, so an image from a private registry cannot be pulled. Build the image from source instead
Environment and redeploysSend environment values through env_file_content. A redeploy runs git reset --hard and git clean -df in the site directory, so uncommitted server-side changes are lost
What a Docker backup holdsNamed volumes, eligible bind mounts, the Compose file and the app's .env, in an encrypted snapshot. The app is stopped while the backup captures and restarted afterwards
Backup toolsTake a backup, list backups, read the count and the settings, change the settings, add a note and delete a backup. Remote copies go to a storage provider you add in the dashboard
RestoresA restore replaces the app's data in place, so it stays a dashboard step: Site, Site Backup, Previous Backups, Restore Backup
Dot-prefixed pathsA 403 on a path that starts with a dot is the dot-path allowlist. It is fixed with docker.allowed_dot_paths in the deploy settings, without a rebuild

Rules Gemini CLI has to follow

  • The Compose file is scanned before the dry run, and the port always comes from the scan, never from a guess.
  • A file that binds ports 80 or 443, publishes no port or pulls from a private registry is not deployed as-is. The agent shows the rewrite, such as publishing 127.0.0.1:<high port>:<app port> and building the image from source, and the change goes into your repository.
  • Creating a site, deploying, redeploying and deleting a backup stop for your approval. A backup runs without a separate prompt but stops the app while it captures, so ask for one at a quiet time.
  • A failed Docker site is retried in place with corrections. It is never deleted and recreated, because it keeps its domain and port.
  • Restoring a backup, adding a backup storage provider and changing a live site's domain are dashboard steps; the agent gives you the path and the dashboard link xCloud returned.

Example prompts

What Can You Ask Gemini CLI to Do for Docker apps?

Type these as written and swap in your own repository, site and server names. Reads and routine actions such as backups, cache purges, PageSpeed scans and vulnerability scans run straight away; creating, deploying, updating, rebooting, deleting, buying or starting a broken-link scan stops and asks first.

Prompt
Scan the compose file on main and list the services and published ports.
Prompt
Deploy this repo to the Frankfurt Docker server as a Compose app. Show the dry run and stop.
Prompt
Back up notes.example.com and add a note that it was taken before the postgres upgrade.
Prompt
Scan the docker-compose.yml in github.com/acme/api and tell me which services and ports xCloud would use.
Prompt
Deploy github.com/acme/shop to the Frankfurt Docker server as a Compose app. Scan the compose file first, show me the services and ports, then wait for my approval before creating anything.
Prompt
Deploy the main branch of github.com/acme/api to my Docker server as a Compose app on a staging hostname.
Prompt
My Compose app on notes.example.com answers 502. Check which port its compose file publishes and which port xCloud is using.
Prompt
Take a backup of the Docker app on notes.example.com now, before I upgrade it, and tell me when it is done.
Prompt
Show the backup settings and the last backup of every Docker app on this team, and list the ones with no schedule.
Prompt
The last deploy of the API site failed. Diagnose it, show me the settings I can correct, fix the build command and retry on the same site.

Gemini CLI and Docker apps: Frequently Asked Questions

What people ask before they let Gemini CLI run Docker apps through xCloud.

What do the xCloud Docker tools look like in Gemini CLI?

Gemini CLI names each tool mcp_ plus the server name plus the operation, so the Compose scan appears as mcp_xcloud_git_compose-scan and the Docker backup as mcp_xcloud_sites_docker_backup. Run gemini mcp list to confirm the xcloud server is registered.

Can Gemini CLI take a Docker backup on a schedule from a headless machine?

A headless machine can connect with an API token that carries the mcp:invoke scope plus read:sites and write:sites in the headers field, so Gemini CLI can take a Docker backup there without a browser. The backup stops the app while it captures, so pick a quiet hour. Restores remain a dashboard step.

Which servers can run a Docker app on xCloud?

Docker servers. Node.js, PHP and static builds use Nginx or OpenLiteSpeed servers, and the Docker deploy on any other stack is refused with an incompatible_server code. An OpenClaw, Hermes, Paperclip or DeepSeek Harness server hosts only the site created at provisioning, so it takes no Docker app.

Why does the agent scan the Compose file before deploying?

xCloud proxies to the host port your file publishes and never rewrites it. The scan lists the services and ports, so the agent picks a port that is free on the server and published by the file instead of guessing.

Why does my Compose app answer 502 after it deployed?

The most common cause is a Compose file that publishes no port: xCloud accepts it, then its nginx has nothing to proxy to. Publish the app on 127.0.0.1 with a high port, such as 127.0.0.1:8080:8080, and redeploy.

Can an agent deploy an image from a private registry?

Not as-is. The deploy runs docker compose pull and never docker login, so a private image cannot be pulled. Build the image from source in the Compose file, or deploy a repository that does.

Can an agent back up and restore a Docker app?

It can take a backup, read the backup list and settings, change the settings, add a note and delete a backup. Restoring replaces the app's data in place, so you do that in the dashboard under Site, Site Backup, Previous Backups.

Can I run WordPress as a Docker app on xCloud?

No. Creating a WordPress site on a Docker server is refused because WordPress is not supported on Docker servers. Use an Nginx or OpenLiteSpeed server for WordPress.

Other agents

Docker apps with Other Agents

The same job, the same xCloud tools, a guide for each client.

Run Your Hosting from Gemini CLI

xCloud MCP, the Agent Skills and the Public API are free with every account. Connect once and ask.