# gagarin > A cloud your coding agent can operate and you can read. gagarin runs your > containers on managed infrastructure. There are no manifest files and no config > files: the API is the only way state changes, which is why neither you nor your > agent can ever be out of sync with what is actually running. ## Deploying If you are an agent reading this to deploy something, you do not need the rest of this site. Install the CLI and everything else is `gg` — there is no HTTP flow to learn, and no endpoint to call by hand: 1. Install `gg`: `brew install gagarin-cloud/tap/gg`, or `go install github.com/gagarin-cloud/gg@latest`, or take a binary from https://github.com/gagarin-cloud/gg/releases and verify its checksum. Then `gg skill install`, which writes the agent skill documenting the rest. The skill ships inside the binary, so it never disagrees with your CLI. 2. `gg login` prints a link and a code, and exits. Give both to your human as printed. There is no address to ask for and no separate signup: it is the same command for a new account and an old one. 3. Your human opens the link, signs in with GitHub or Google, checks that the page shows the same code, and approves. A new account starts with $5 on it. 4. Once they say they have, run `gg login` again. It collects that approval and stores credentials locally. Nothing is exported, and you never handle a secret. 5. `gg init ` creates the project everything else is named for. 6. `gg ship /:` builds the current directory, pushes it, and runs it. `gg deploy` is that last step on its own, for an image already in the registry. An MCP client (claude.ai, ChatGPT, Claude Code) can connect to `https://mcp.gagarin.cloud/mcp` instead of installing anything; your human signs in with GitHub or Google when the client asks them to. Deploying is free. **Deleting anything asks your human again**, every time — so an agent can ship but cannot destroy a client's production on its own. A deploy describes one revision of a service and nothing else. `--env` / `--env-file` set the environment, replaced wholesale rather than merged, because that is what a rollback puts back. `--volume` keeps a directory across restarts and is set once, at the first deploy. Everything else a service has is declared by its own command, and a deploy can never release it: `gg deps add` for the other services and resources this one may call, and `gg domain add` for every address it answers on. A dependency that is not declared does not connect — the readable graph is the firewall, not a diagram beside it. `gg deploy --deps` may add an edge, so that a service needing a database can be declared and deployed in one call; it cannot withdraw one, and a deploy that omits it changes the graph not at all. Rotating a credential is therefore one command — `gg resource rotate` — and every service holding it restarts with the new one. Nothing has to be found and redeployed, because nothing was copied: a password pasted into three deploys needs three more to rotate, and the one forgotten authenticates with a revoked key until somebody notices. There is one place to change instead. An `external` holds values a user typed in rather than ones gagarin minted, so rotating one means supplying the new ones: `--set KEY=value` changes that key and leaves the rest of the bundle alone, and `--env-file` replaces the bundle entire, dropping anything not in it. Most rotations are the first kind — one key leaked and the other settings did not — and the command names whatever stopped being published. Declaring a dependency on a resource is also what hands over its credentials. The resource publishes them under its own name — a postgres called `db` gives `DB_URL`, `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_DATABASE` — and the platform derives them from the graph every time it starts the pod rather than copying them into the service's stored environment. So there is nothing to go stale, no redeploy can forget them, and a rollback restores the image and the environment you deployed with rather than a password that is no longer anybody's. A service is private until `gg domain add /` gives it an address; the same command with a hostname after it adds a name the user owns, and the service then answers on both. One verb, because they are one fact. There is no `--public` flag and there deliberately is not: an address outlives any image, and a flag that hands one out can withdraw it by being forgotten, which from outside looks exactly like an outage nobody caused. A name the user owns is two steps, of which only the first is gagarin's: the DNS record is theirs to create, and nothing is served over HTTPS on that name until it exists. `gg status` says which side it is waiting on — their DNS, or our certificate. Taking an address away needs a human's approval, the same one destroying a service needs: we email them a button, and they approve signed in to the console as themselves. `gg history` and `gg rollback` put a previous image and environment back through that same gate; they restore neither the graph, nor any address, nor the volume. ## Docs - [gg on GitHub](https://github.com/gagarin-cloud/gg): the CLI, MIT licensed, with released binaries and checksums for linux, macOS and Windows. We do not ask anyone to pipe a script into a shell. - [The model](https://gagarin.cloud/docs/model): projects, services, resources, dependencies. One project per application; a service is a container image that runs; a project's id, not its name, is what appears in hostnames; a service can also answer on a domain its owner controls. - [Error contract](https://gagarin.cloud/docs/errors): every error carries a stable `code` and a `fix_hint`. Act on the code, not the prose. - [What gagarin will never build](https://gagarin.cloud/docs/never): the refusal list, with reasons. Published on purpose — it is the thing that keeps one way of doing something from becoming four. ## Optional - [Why coherence](https://gagarin.cloud/docs/why): clouds are not too complex, they are incoherent — four ways to change the same state and no authoritative one. Building for agents is what finally makes a cloud readable by people. - [gg eject](https://gagarin.cloud/docs/eject): emits the Kubernetes manifests the platform converges the cluster toward, so you can leave in an afternoon.