Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

## Features

- **From zero to URL** — never used Docker, GitHub, or Kubernetes? The skills meet you where you are, one command at a time, including building and pushing your first image
- **Create a cluster** in one prompt — sensible defaults, no preset/zone/autoscaling questions
- **Deploy any container** — Claude writes the Namespace, Deployment, and Service for you
- **Real URLs via HTTPRoute** — `internal` by default, with an explicit security check before exposing anything publicly
Expand Down Expand Up @@ -54,6 +55,8 @@ Claude: [creates HTTPRoute on the internal gateway]
Live at http://shop.apps.example.com — try it out.
```

Don't have an image yet — or not sure what an image is? Start the same way. The plugin notices what's missing and walks you through containerizing, building, and pushing first.

## What's in the box

Eight composable skills. All are user-invocable, so you can ask for any of them directly — or just describe what you want and the right one runs.
Expand Down
7 changes: 4 additions & 3 deletions skills/getting-started/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ command -v oc >/dev/null 2>&1 && echo "oc: ok" || echo "oc: MISSING"
command -v docker >/dev/null 2>&1 && echo "docker: ok" || echo "docker: missing (optional)"
```

- **`indev` missing** → stop. Send the user to https://developers.intility.com to install it. Nothing else works without this.
- **`oc` missing** → stop. Same page has install instructions.
- **`docker` missing** → fine to continue. Only `prepare-app` uses it, and that's optional.
- **`indev` missing** → stop. On macOS the quickest path is `brew install intility/tap/indev`; otherwise https://developers.intility.com has instructions. Nothing else works without this.
- **`oc` missing** → stop. macOS: `brew install openshift-cli`; otherwise same page as above.
- **`docker` missing** → fine to continue. Only `prepare-app` uses it, and only when an image still needs to be built or checked — it helps the user install Docker at that point.

If everything is present, don't say anything — move on silently. Only narrate the check if something is missing.

Expand Down Expand Up @@ -109,6 +109,7 @@ To add another app, just ask: "deploy another app" — it'll go in its own names
## Tone reminders

- Plain language. Avoid "namespace", "manifest", "ingress" on first mention — say what they *do* first, then introduce the term once.
- Never assume prior Docker, GitHub, git, or Kubernetes experience. Many users are shipping their very first app — that's exactly who this plugin is for, and the skills have from-zero paths for each gap (e.g. `prepare-app` can walk them from "no Dockerfile, no registry" to a pushed image).
- One command at a time. Don't dump three commands and hope they pick one.
- Don't apologize for asking questions. One question, then move on.
- If they're stuck, suggest the next concrete step. Don't open with troubleshooting trees.
Expand Down
17 changes: 13 additions & 4 deletions skills/prepare-app/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ Q: "I couldn't find a Dockerfile. Do you have one?"
- "I have an image already, no Dockerfile needed"
```

If "No, not yet": don't try to write one for them on the spot — ask what the app is (language, framework, how it starts), then draft a minimal `Dockerfile` using one of the templates in [references/minimal-dockerfile.md](references/minimal-dockerfile.md). Pick the closest match, adapt names and ports to their app, drop in the file, and stop. They build and push it themselves — this plugin doesn't run `docker build`.
If "No, not yet": don't try to write one for them on the spot — ask what the app is (language, framework, how it starts), then draft a minimal `Dockerfile` using one of the templates in [references/minimal-dockerfile.md](references/minimal-dockerfile.md). Pick the closest match, adapt names and ports to their app, and drop in the file.

Then walk them through building and pushing it using [references/build-and-push.md](references/build-and-push.md) — one command at a time, they run each one themselves (this plugin doesn't run `docker build`). Don't assume they've used Docker, GitHub, or a registry before; the walkthrough covers the from-zero path including getting a token.

After they confirm the image is pushed, continue with Step 2.

## Step 2 — Confirm there's a pushed image

This plugin doesn't build or push images for the user — that varies too much by registry. We just need an image reference.
This plugin doesn't run `docker build`/`docker push` for the user — but it does guide them through running those themselves (see Step 1 / the build-and-push walkthrough). What this step needs to end with is an image reference.

```
Q: "What's the image reference for your app?"
Expand All @@ -55,7 +57,7 @@ If they don't know what an image reference is, give them one sentence:

> It's the address where your built image lives. After `docker push`, it's the same string you `docker push`-ed to — registry + repo + tag.

If they haven't pushed yet, point them at the registry they're using (or suggest `ghcr.io` if they're on GitHub) and **stop here**. Tell them: "Once you've run `docker push`, come back and we'll deploy it." Do not try to build or push for them.
If they haven't pushed yet, don't just send them away — offer to walk them through it right now using [references/build-and-push.md](references/build-and-push.md). It covers the full from-zero path: Docker Desktop, a free GitHub account if they don't have one (no git knowledge needed — the account is just the key to the registry), token, login, build, push. One command at a time; they run each themselves. If their team already has a different registry, the same steps apply with that registry's address and login.

## Step 3 — Optional: sanity check the image exists

Expand All @@ -71,7 +73,10 @@ Skip this step if `docker` isn't installed locally — it's a nice-to-have, not

## Step 4 — What port does the app listen on?

This is the single most-forgotten thing later. Ask now:
This is the single most-forgotten thing later — and "what port?" is a question many users genuinely can't answer. So **look before you ask**: check the `Dockerfile` for `EXPOSE`, and the code for the usual suspects (`package.json` start script, `app.listen(...)`, `PORT` env defaults, framework config).

- **Found one** → confirm it in one line: "Looks like your app listens on port 3000 — right?" Most users just say yes.
- **Can't tell** → ask, with hints:

```
Q: "What port does your app listen on inside the container?"
Expand All @@ -82,6 +87,8 @@ Q: "What port does your app listen on inside the container?"
- Other (free text)
```

If they have no idea even with the hints, offer to look through the code together — it's in there somewhere.

## Step 5 — Hand off

Pass forward to `deploy-app`:
Expand All @@ -96,9 +103,11 @@ app:
## Tone

- Don't lecture them on containers. If they don't know what an image is, give one sentence, then move on.
- Never assume they've used Docker, GitHub, or git before. Check with one short question, then meet them where they are — the build-and-push walkthrough exists exactly for this.
- If they're missing a Dockerfile and the conversation goes deep, *stop* and write a Dockerfile in a separate turn. Don't conflate "deploy" with "containerize from scratch" — these are different sessions.

## References

- [references/minimal-dockerfile.md](references/minimal-dockerfile.md) — copy-paste Dockerfile templates for Node, Python, Go, and static sites
- [references/build-and-push.md](references/build-and-push.md) — from-zero walkthrough: Docker Desktop, GitHub account, token, login, build, push
- [references/usage-examples.md](references/usage-examples.md) — typical conversations (ready to go, no Dockerfile, private registry, image not pushed)
65 changes: 65 additions & 0 deletions skills/prepare-app/references/build-and-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Build and Push Your First Image

A walkthrough for users who have never built or pushed a container image. Guide them through it **one command at a time** — show a command, let them run it (or run it for them only if they explicitly ask), confirm it worked, then show the next. Never paste the whole list at once.

The flow below uses GitHub's registry (`ghcr.io`) because it's free and most common. If their team already has another registry, the same steps apply — only the address and login change.

## Before starting, check quietly

- **Docker installed?** `command -v docker`. If missing: they need Docker Desktop — https://www.docker.com/products/docker-desktop/ — install, open it once, come back. (On macOS: `brew install --cask docker` also works.)
- **GitHub account?** Ask in one line. If they don't have one, it's free at https://github.com/signup — they don't need to know git or use repositories; the account is just the key to the registry.

## Step 1 — Get a token to log in with

ghcr.io doesn't accept your GitHub password. You need a **classic personal access token**:

1. Go to https://github.com/settings/tokens → "Generate new token (classic)"
2. Name it something like `registry`, tick the **`write:packages`** scope (this auto-ticks `read:packages`)
3. Generate, and copy the token (starts with `ghp_`) — you won't see it again

Tell the user to keep it somewhere safe; it's also what `deploy-app` will ask for later so the cluster can pull the image.

## Step 2 — Log Docker in to the registry

```bash
docker login ghcr.io -u <github-username>
```

When it asks for a password, paste the token from Step 1 — not the GitHub password. Success looks like `Login Succeeded`.

## Step 3 — Build the image

Run from the directory with the `Dockerfile`:

```bash
docker build -t ghcr.io/<github-username>/<app-name>:v1 .
```

One-line explanation to give: *"`-t` names the image — the name doubles as the address it will be uploaded to. `v1` is the version tag; you'll bump it for each release."*

Notes:
- The name must be **all lowercase** — `ghcr.io/Me/MyApp` is rejected.
- Don't forget the trailing `.` — it means "build from this directory".
- On Apple Silicon Macs, build for the cluster's architecture: add `--platform linux/amd64`.

## Step 4 — Push it

```bash
docker push ghcr.io/<github-username>/<app-name>:v1
```

When the progress bars finish, the image is in the registry. That full string — `ghcr.io/<github-username>/<app-name>:v1` — is the **image reference** the rest of the journey needs.

## Good to know afterwards

- **ghcr images are private by default.** That's fine — `deploy-app` sets up cluster pull access with one question (it'll ask for the same username + token).
- **Shipping a new version later:** rebuild and push with a new tag (`:v2`), then say "update <app> to v2" — the `update-image` skill does the rest.

## When things go wrong

| Symptom | Likely cause |
|---|---|
| `denied` on push | Token missing the `write:packages` scope — make a new one |
| `unauthorized` on login | Pasted the GitHub password instead of the token |
| `invalid reference format` / repository name errors | Uppercase letters in the image name — lowercase everything |
| Build fails | That's a Dockerfile/app problem, not a registry problem — read the error together and fix the Dockerfile |
97 changes: 69 additions & 28 deletions skills/prepare-app/references/usage-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,76 @@
```
You: My app is at ghcr.io/me/shop:v1, listens on 3000.

Claude: [find . -name Dockerfile → ./Dockerfile found]
Claude: [Glob Dockerfile → ./Dockerfile found]
[docker manifest inspect ghcr.io/me/shop:v1 → ok, public]

Image looks good. Port 3000. Handing off to deploy-app.
```

---

## Example 2 — No Dockerfile yet
## Example 2 — Never deployed anything before

User has code, no Dockerfile, no Docker, no GitHub account. The skill walks the whole path — one command at a time, the user runs each one.

```
You: I want to deploy my Node app but I don't have a Dockerfile.
You: I built a little internal tool in Node. I've never deployed anything.
Can you get it online?

Claude: What does your app do, and how do you start it locally?
You: It's a Next.js app. `npm start` runs it on port 3000.
Claude: Absolutely — we'll do it step by step. First I'll package your app so
the platform can run it. How do you start it locally?
You: npm start, it says it's on localhost:3000.

Claude: [reads templates from references/minimal-dockerfile.md]
[writes ./Dockerfile + .dockerignore]
Claude: [writes ./Dockerfile from references/minimal-dockerfile.md, port 3000]

Here's a starter Dockerfile that should work. Run:
docker build -t ghcr.io/<you>/<app>:v1 .
docker push ghcr.io/<you>/<app>:v1
Done — this file describes how to run your app anywhere. Next we need
somewhere to upload it. Do you have a GitHub account?
You: No.

Then come back and we'll deploy it.
```
Claude: No problem — it's free and you won't need to learn git; the account is
just the key to GitHub's image storage. Create one at
github.com/signup, then tell me your username.
You: ok, I'm "annab"

Claude: Great. Now a token so Docker can log in as you:
github.com/settings/tokens → "Generate new token (classic)" →
tick "write:packages" → Generate. Copy the ghp_... string.
You: got it

Claude: Run this, and paste the token when it asks for a password:

docker login ghcr.io -u annab

You: Login Succeeded

Claude: Now build:

docker build -t ghcr.io/annab/mytool:v1 .

You: done, lots of output but it finished

Claude: Last one — upload it:

docker push ghcr.io/annab/mytool:v1

The skill stops here. Building and pushing is the user's job.
You: done!

Claude: Your app now lives at ghcr.io/annab/mytool:v1. It's private by
default, which is fine — I'll set up cluster access when we deploy.
Handing off to deploy-app.
```

---

## Example 3 — Private registry

```
You: Image is at private.registry.example.com/team/app:v1, port 8080.
You: Image is at ghcr.io/team/app:v1, port 8080. It's private.

Claude: [docker manifest inspect → unauthorized]

Looks like that image is in a private registry. We'll need to set up an
image pull secret in the cluster — deploy-app will handle that, just be
ready with your registry username + access token.

Continuing.
Noted — deploy-app will set up cluster pull access (one question:
username + token, once for the whole cluster). Continuing.
```

---
Expand All @@ -56,21 +84,34 @@ Claude: [docker manifest inspect → unauthorized]
```
You: I have a Dockerfile but I haven't pushed anywhere.

Claude: I need an image reference (something like ghcr.io/<you>/<app>:v1) before
we can deploy. The cluster pulls from a registry, not from your laptop.
Claude: The cluster pulls your app from a registry, not from your laptop —
so let's get it uploaded. It's three commands and I'll walk you
through each. Do you have a GitHub account?
You: yes

Claude: [continues with the token → login → build → push walkthrough from
references/build-and-push.md, one command at a time]
```

---

## Example 5 — Port detected from the code

```
You: Deploy this, image is pushed at ghcr.io/me/api:v1.

Claude: [Glob Dockerfile → found; reads it → EXPOSE 8000]

Pick a registry — GitHub's ghcr.io is free for public repos and works
with your GitHub login. Then:
docker build -t ghcr.io/<you>/<app>:v1 .
docker push ghcr.io/<you>/<app>:v1
Looks like your app listens on port 8000 — right?
You: yes

Once it's pushed, come back and tell me the image reference.
Claude: Handing off to deploy-app.
```

---

## What this skill won't do

- Run `docker build` or `docker push` for you
- Run `docker build` or `docker push` itself — you run them, it guides you through each one
- Write a Dockerfile without you telling it what the app is
- Set up a registry account
- Create accounts for you (but it will point you at exactly the right signup and token pages)
2 changes: 1 addition & 1 deletion skills/update-image/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,4 @@ See [references/usage-examples.md](references/usage-examples.md) for typical con

- Don't use `kubectl edit` / `oc edit` — opens an editor, fragile.
- Don't re-apply the whole `deployment.yaml` from disk unless the local file is already updated. Otherwise you'll roll back any image bumps that happened via `oc set image`.
- Don't suggest `latest` as a tag. Encourage immutable tags (commit SHAs, version numbers).
- Don't suggest `latest` as a tag. Encourage tags that never move — version numbers like `v2`, `v3` — so it's always clear which build is running and rollback has something to roll back to.