본문으로 건너뛰기
cccskills
무료GitHub에 공개

deploy-app-from-local

Deploy a local checkout to a production Hetzner App using the manual image-import runbook. Use when the user asks to ship local working-tree code to a live bex App rather than deploy from remote Git. Arguments are the local repo path and app name.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex스타 574(GitHub 574 + cccskills 0)
연동 도구Kubernetes

실행 점수 미검증

설치 방법 보기

포함된 파일(2)

  • SKILL.md5.1 KB
  • agents/openai.yaml224 B

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Task: deploy a local checkout to prod Hetzner (manual image-import runbook)

Use this runbook only when the code to deploy exists on local disk and not in Git (uncommitted or unpushed work). Committed code goes through the operator's in-cluster build (BuildKit/kpack Jobs, lego/operator/internal/build/), which this skill bypasses by running docs/ADR004-app-deployment.md's manual image-import runbook end-to-end. Do not use the restart verb as a substitute for a deploy — it only rolls pods on the App's existing spec.image; it never rebuilds anything.

The image is built from whatever is on disk in $ARGUMENTS's repo path right now, not from origin/main. If you want "latest remote main" instead, git pull --ff-only first.

Step 0 — Confirm scope with the user before touching prod

This SSHes into a live Hetzner node and patches a running App CR — state a one-line plan (repo, app name, target image tag) and get a go-ahead before Step 4 (the actual ctr import + kubectl patch). Steps 1–3 (discovery, build, smoke test) are safe/local and don't need to wait for that confirmation.

Step 1 — Fetch the app-cluster kubeconfig (self-managed, no infra node)

There is no management cluster — scripts/fetch-app-kubeconfig.sh discovers a control-plane node via the hcloud API (label caph-cluster-bex) and SSH-fetches /etc/kubernetes/admin.conf:

# from the bex repo root (where this command runs)
set -a; source ./.env; set +a
# default key is ~/.ssh/id_bex (see scripts/fetch-app-kubeconfig.sh); override only if your key is elsewhere
BEX_SSH_KEY_PATH=~/.ssh/id_bex bash scripts/fetch-app-kubeconfig.sh /tmp/bex-app.kubeconfig
export KUBECONFIG=/tmp/bex-app.kubeconfig
kubectl get app <app-name> -o yaml   # baseline: current image, port, generation, revision

Never print $HCLOUD_TOKEN or kubeconfig contents (per repo rules) — only read specific jsonpath fields.

Step 2 — Discover the node the App runs on (import target)

Apps run on the tenant pool (bex-worker-*), not the control plane — the image must be imported into the containerd of the node hosting the App's pod:

NODE=$(kubectl get pods -n default -l app.bex.co/app=<app-name> -o jsonpath='{.items[0].spec.nodeName}')
APP_NODE_IP=$(curl -sf -H "Authorization: Bearer $HCLOUD_TOKEN" \
  "https://api.hetzner.cloud/v1/servers?per_page=50" \
  | python3 -c "import json,sys; print([s['public_net']['ipv4']['ip'] for s in json.load(sys.stdin)['servers'] if s['name']=='$NODE'][0])")

(If the pod is Pending with no node yet — e.g. first deploy — import into every bex-worker-* node instead. ⚠ Known fragility: ctr-imported images live only in that node's containerd; an autoscaler node replacement loses them and the App falls to ImagePullBackOff until re-imported — re-run this runbook then.)

Step 3 — Build + smoke-test — laptop, from the local repo path in $ARGUMENTS

cd <repo-path>
SHA=$(git rev-parse --short HEAD)
docker build --platform linux/amd64 -t <app-name>:$SHA .   # amd64 required — Hetzner node is x86_64
docker run -d --rm --name smoke -p 127.0.0.1:3999:<container-port> <app-name>:$SHA
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3999/   # expect 200
docker stop smoke

Use a fresh tag (git sha, never :latest) — the operator sets no imagePullPolicy, so k8s defaults to IfNotPresent; reusing a tag would silently serve the node's cached image.

Step 4 — Import into the app node's containerd — laptop → app node (confirm with user first, see Step 0)

docker save <app-name>:$SHA | ssh -i ~/.ssh/id_bex "root@${APP_NODE_IP}" \
  'ctr -n k8s.io images import -'

Step 5 — Patch the App CR — laptop → apiserver → operator

KUBECONFIG=/tmp/bex-app.kubeconfig kubectl patch app <app-name> --type merge \
  -p "{\"spec\":{\"image\":\"<app-name>:$SHA\"}}"

This bumps metadata.generation, which is what makes the operator reconcile (it early-returns when already Running at the current generation).

Step 6 — Watch the rollout and verify the edge serves the new code

KUBECONFIG=/tmp/bex-app.kubeconfig kubectl rollout status deployment/<app-name>
KUBECONFIG=/tmp/bex-app.kubeconfig kubectl get app <app-name>   # PHASE Running, REVISION bumped
curl -s https://<app-name>.onbex.co/ | grep -i '<something only in the new build>'

A 200 alone doesn't prove anything — grep for content that only exists in the new commit (e.g. the new blog post title, a changed string). This is the step that actually confirms a deploy happened.

Step 7 — Report

App name, old image tag → new image tag (git sha), old revision → new revision, and the content check that proved the new code is live. Clean up /tmp/bex-app.kubeconfig when done.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Deploy a bex App to the current Kubernetes cluster and verify it reaches Ready. Use when the user asks to deploy a render.yaml (or legacy bex.yml) or the sample app and validate the rollout end to end. Optional argument: path to render.yaml.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

loopx

무료

Autonomously drain a `.pm` workstream — triage every open item (milestone or inbox-note task), then work it to done, park it in `blocked/`, or delete it as invalid, until the workstream has no open items left. Use when the user asks to "loop", drain, or clear a whole workstream's backlog (e.g. `/loopx w1`). Sequential, not interval-based; for a timed poll use /loop.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

mermaid

무료

Create concise, syntax-verified Mermaid architecture diagrams. Use when the user asks to diagram a repository component, document, system, dependency flow, or supplied description in Mermaid.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

Stand up or scale the local CAPD mock cluster and deploy the bex operator into it. Use when the user asks to create, inspect, or resize the repository's local development cluster. Optional argument: scale N.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

pm

무료

Inspect and maintain the repository's .pm workstreams, inbox notes, milestones, and tasks. Use when the user asks for PM board status or requests a supported board mutation such as creating, promoting, adding, or completing work.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

Analyze and decompose a product topic into a text-only proposal for the repository's .pm board. Use when the user wants to pressure-test scope, size milestones, identify dependencies, or prepare exact PM board commands without writing board files.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

bex-co/bex5742026년 10월 26일 업데이트

bex-co의 스킬 모두 보기

이 스킬의 문제 신고