Deploy with ease. Maintain without fear.
Your agent ships it. Alerts tell you when it breaks, logs say why, project memory keeps the context, and nothing gets deleted without your approval.
- 01It installs gg and the Gagarin skill.
- 02It runs gg login and hands you a link and a code.
- 03You sign in with GitHub or Google, check the code matches, and approve. $5 of credit is waiting, no card.
- 04It ships, and tells you the HTTPS address.
Teach your agent Gagarin once.
Install the plugin, the skill or the connector, and every session after that knows the commands, the rules and the errors. Or skip it: the sentence above works in any agent.
One plugin, everything in it.
The skill, the MCP server, /gagarin:setup, /gagarin:status, /gagarin:ship, and a subagent that takes a repository to a working HTTPS URL.
/plugin marketplace add gagarin-cloud/claude-plugin/plugin install gagarin@gagarin-cloud/gagarin:setupThen say what you want: “deploy this”, “add a database”, “deploy on every push”.
You type one sentence. Your agent does the rest.
The message is typed. Press enter.
Nothing deployed yet.
Setting up one backend on managed Kubernetes took me 22 hours. On Gagarin it takes under three.
In October, while building Gagarin, I put my other company’s production backend on a new cloud: an API, its web apps, a CMS, Postgres, object storage and the cron jobs. The code already existed. Everything around it I set up from scratch: ingress, certificates, secrets, monitoring, CI. I knew the stack well, and it still took me two days. Each mark below is one of my commits.
Viktor, founder of Gagarin
- day 1, 10:34 The cluster is up. Now the real work starts.
- day 1, 20:25 Monitoring and alerts, then an hour fixing them
- day 2, 00:14 Midnight: I move the production database
- day 2, 13:46 I delete the git server I built last night
- day 2, 20:07 Backups, and a drill to prove they restore
- 5 minCreate the project
gg init backend - 5 minTwo Postgres databases, one for the app and one for the CMS
gg resource add backend/app postgres - 25 minFreeze writes, dump the old databases, restore them through a local tunnel
gg connect backend/app - 10 minTwo extra database users with narrow grants, in SQLby hand
gg connect backend/app - 15 minThree buckets, then copy the objects across
gg resource add backend/uploads s3 - 10 minFive sets of secrets, as external resources
gg resource add backend/api-env external --env-file .env.api - 20 minSeven services, from the images already built
gg deploy backend/api:8080 api:v41 --deps app --deps api-env - 10 minTwenty cron jobs, generated from the old jobs table
gg run backend/refund-reports ether:v41 --schedule "* * * * *" --deps app - 15 minA small router, because the main domain sends paths to different services
gg deps add backend/edge api web mcp www - 15 minDomains, and their DNS records at the registrarby hand
gg domain add backend/edge example.com - 20 minCI in six repositories deploys with gg ship
gg creds create --name "gitlab: api" - 2 minAlerts on, with the switch in the console on each phone, then a testby hand
my.gagarin.cloud → backend → alerts - 10 minCheck every route and every job
gg status backend
Flip one switch, and your phone tells you what broke.
You write no alert rules and wire up no pager. Open the project in the console on your phone and turn alerts on. When a service crashes, the notification names the service and the reason, and for a memory crash it names the size to move to.
Your logs are already there, for you and for your agent.
Everything a service prints is kept for a week, including the containers that crashed or were replaced. You read it in the console. Your agent reads the same lines with gg logs, finds the panic, and ships the fix.
The latest 12 lines api printed. A week is kept, crashed and replaced containers included. Not a stream — reload to see further.
12026/10/21 14:02:11 listening on :808022026/10/21 14:03:40 GET /api/orders 200 12ms32026/10/21 14:03:41 POST /api/checkout 200 31ms42026/10/21 14:03:52 GET /api/orders 200 9ms52026/10/21 14:04:07 POST /api/checkout 500 3ms6panic: runtime error: invalid memory address or nil pointer dereference7[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x6c2f1a]8goroutine 41 [running]:9main.(*Cart).Total(0x0)10 /src/cart.go:48 +0x1a112026/10/21 14:04:09 listening on :8080122026/10/21 14:04:12 GET /api/orders 200 11ms
Your agent remembers why you built it that way.
Every project keeps a memory its agents share: decisions and their reasons, gotchas, conventions. A new session reads the briefing before it reads the code, so it stops proposing the fix you already tried and reverted. Memory costs $0.10 a month per thousand memories.
- overview
- architecture
- decision
- convention
- gotcha
- howto
- reference
- state
- ★ pinned
memory_get(saas, [7])## #7 decision · Sessions stay in Postgres, not valkey tags: sessions, auth · pinned · importance 5 · updated 2026-10-03 valkey keeps nothing across a restart: the first one logged every user out. Sessions live in pg’s sessions table; valkey may cache in front of it, never instead of it. ↔ #12 Login reads the sessions table on every request · #15 valkey restarts during deploys · #13 valkey caches rendered invoice PDFs, nothing else · #3 api, worker and web; pg is the only store of record
#7 is a decision. Its links are lit; thicker ones have been followed more.
Your agent builds. Only you can take things away.
Four actions break something that is running. Each one stops and emails you a button, and no flag hands that button to an agent. One click covers fifteen minutes, so a clean-up needs one approval, not ten.
gg destroyDeleting a service, a database or a projectgg domain rmTaking an address off the internetgg deps rmWithdrawing a route between two servicesgg transferHanding a project, and its bill, to someone else
- 1 your agent asks
- 2 your inbox
- 3 the console
- 4 your agent goes on
CI with one secret and no service accounts.
One command mints a credential for your pipeline. Put it in a secret, and the workflow is five steps you can read top to bottom. No IAM role to assume, no registry policy, no cluster role binding.
- It can deploy. It cannot destroy, and no flag turns that on.
- It expires: 90 days by default, 365 at most, and there is no never.
- It cannot mint another, so a leaked one cannot issue its own replacements.
- It is shown once. Gagarin keeps a hash.
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
GAGARIN_TOKEN: ${{ secrets.GAGARIN_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: install gg
run: go install github.com/gagarin-cloud/gg@latest
- name: log docker in to the Gagarin registry
run: gg registry login
- name: build and publish
run: gg build acme/web:${{ github.sha }} --push
- name: release
run: gg deploy acme/web:8080 web:${{ github.sha }} --env-file .env.production
- name: say what the cluster is doing
run: gg status acmeLeaving takes one command.
gg eject writes out the Kubernetes objects Gagarin runs for your project: the real ones, with your routes as network policies and your environments as secrets. Apply them to any cluster, move your images and your data, and you have moved in an afternoon.
imagesstill in Gagarin’s registry: pull them, push them where you likevolume datathe claims come back empty; pg_dump works the way it always hascluster, domain, billingyours to sort out
# saas — exported from Gagarin
#
# These are the Kubernetes objects Gagarin runs for this project: not a
# description of them, the objects themselves. Applying this to any cluster with
# an ingress controller gives you what you had.
#
# kubectl apply -f this-file.yaml
# …
---
kind: Namespace
metadata: { name: saas }
# --- api -------------------------------------
---
kind: NetworkPolicy
metadata: { name: api, namespace: saas }
---
kind: Secret
metadata: { name: api, namespace: saas }
---
kind: Deployment
metadata: { name: api, namespace: saas }
---
kind: Service
metadata: { name: api, namespace: saas }
# --- pg --------------------------------------
---
kind: NetworkPolicy
metadata: { name: pg, namespace: saas }
---
kind: Secret
metadata: { name: pg, namespace: saas }
---
kind: PersistentVolumeClaim
metadata: { name: pg, namespace: saas }
---
kind: Deployment
metadata: { name: pg, namespace: saas }
---
kind: Service
metadata: { name: pg, namespace: saas }
# --- web -------------------------------------
---
kind: NetworkPolicy
metadata: { name: web, namespace: saas }
---
kind: Secret
metadata: { name: web, namespace: saas }
---
kind: Deployment
metadata: { name: web, namespace: saas }
---
kind: Service
metadata: { name: web, namespace: saas }
---
kind: Ingress
metadata: { name: web, namespace: saas }
# --- worker ----------------------------------
---
kind: NetworkPolicy
metadata: { name: worker, namespace: saas }
---
kind: Secret
metadata: { name: worker, namespace: saas }
---
kind: Deployment
metadata: { name: worker, namespace: saas }
---
kind: Service
metadata: { name: worker, namespace: saas }Three numbers. No tiers.
You pay for what runs, by the minute. There is no plan to choose, no seat to buy, no bandwidth meter, and no price that appears only after a call.
Any service, resource or job while it is up. Call it $10 a month for a small one. Stopped is $0.
Volumes and database storage. It only grows when you ask it to.
Not discounted — not metered. Domains and certificates are part of the platform, and so is the person who answers your email.
New accounts start with $5 on the house and no card is asked for until it runs low. We warn you before the balance reaches zero; if it does, your services stop and nothing is deleted — volumes, domains and data wait for you to put money back.
The full price list, including what a typical project costs →What the price includes: the ops work you stop doing →Let’s get your project online together.
Book half an hour on a video call. Bring your code, or just your questions, and we put it on Gagarin side by side. You leave with an address; I leave with a list of what to make easier.

- Bring your project, or just your questions.
- We deploy it together, and you leave with an address.
- Anything that slowed you down goes on my list to fix.
Don’t take our word for it.
This panel reads the platform’s health endpoint from your browser, right now: the same URL our monitoring watches around the clock. No credential, no status page in between.
Reading the platform from your browser… api.gagarin.cloud/healthz/platform needs no credential and answers 200 only when all three of the above do.
The things people ask first.
So you’re like Railway?
On the surface, yes: containers, databases, domains, an agent that drives it. Most platforms cover that ground now, and most of them draw a dependency graph too. The difference is what the graph does. On every one whose documentation we have read, an edge is a variable reference, and on the private network every service can reach every other whether the line is drawn or not. Here the graph is the firewall, the credential store and the delete guard, because there is exactly one place the truth lives and everything else is derived from it.
What if we outgrow it and want our own cluster?
Some teams, as they grow, want a Kubernetes cluster they run themselves, with every knob exposed. gg eject prints the Kubernetes manifests the platform itself reconciles from, out of the same renderer, so they cannot drift from what is running. Your images were always yours, in a registry you can pull from. The long version.
What are the limits?
Each database runs as a single instance with nightly backups kept fourteen days; replication and point-in-time recovery are not part of the service, so data you cannot afford to lose a day of belongs in a second copy as well. Services run at the size you choose rather than autoscaling. One region: Paris. What we have decided never to build is public, with the reasons. That list.
Can my agent really drive it?
That is the assumption the whole thing was built on. Every error carries a stable code and a fix_hint, so an agent branches on the code instead of reading tea leaves. The agent skill is published from the same repository as the Claude Code plugin and the MCP server, and a check there runs every command it names against the released CLI. Point yours at llms.txt and it will take it from there.
Does the safety get in my way?
It gets in the way of exactly five things, and shipping is not one of them. You can deploy, migrate, roll back, add a domain, resize, and read anything, all without asking anyone. Deleting a service, destroying a resource and removing a live address are what wait on a button in your inbox, pressed while signed in as you — each of them a thing you do a handful of times a year, and each of them a thing you cannot undo.
Is my data in the EU?
Managed Kubernetes at Scaleway in fr-par, Paris. A French company, French data centres, EU law. Everything the platform holds is there — your services, your volumes, your databases, your project memory — and none of it is replicated anywhere else. The handful of companies that see any part of it, and exactly which part, are named in the privacy policy: we list them rather than saying “our providers”, because that is not something you can check.
Put one project on it this afternoon.
Sign in with GitHub or Google, and the account exists. No password, no list, no invitation, no card — and $5 of credit waiting, which is about three weeks of a small service.
Your agent gets in the same way. It runs gg login and hands you a link and a code; you sign in, check the code matches, and approve. Claude and ChatGPT connect to mcp.gagarin.cloud/mcp and ask you to sign in just the same. Nobody can sign you up by typing your address, because there is no address to type.