用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/htlin222/dotfiles --skill vm-docker命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
依 ticket/issue 產出初版實作 — 解析需求、從最新 develop 切出符合命名規範的分支、寫出實作、跑既有測試與 lint、conventional commit,然後交棒給 /simplify。Use when the user types /develop, or asks to start implementing a ticket, issue, or feature request end-to-end from requirement to first commit.
Put a website behind a Cloudflare Access (Zero Trust) login gate, or remove one, entirely from the CLI — no dashboard GUI. Use when the user wants to password/email-protect a hostname, gate a Cloudflare Pages or Workers site, restrict a site to specific emails, set up Zero Trust Access, or asks about "cf-gate". Manages Access applications and allow-email policies via the Cloudflare API using a token in the skill's .env. Note: wrangler does NOT manage Access — this uses the Cloudflare REST API directly.
Curate a GitHub repository's wiki (the separate repo.wiki.git) into a coherent, tightly written set of pages: Home, Introduction (project + features), Roadmap, Gotchas/Lessons, Tech Debt, and an Architecture page taught through the book *Head First Software Architecture* — with mermaid diagrams, in the repo's own language and style, then commit and push. Use when the user wants to create, update, curate, or document a GitHub repo's wiki; write or refresh wiki pages; add an architecture / design page to a wiki; enable a wiki; or asks for "/wiki-git". Handles both first-time wikis and updates to existing ones, and can fan out across many repos.
基于 SOC 职业分类
正在显示 SKILL.md
| name | vm-docker |
| description | Deploy Docker services on VM with Traefik and Homepage. Use for VM container deploys. |
Deploy Docker services on the VM (Pop!_OS). Web services go behind Traefik (port 80) and register on Homepage (dashboard at /).
vm.local (mDNS) — use for app CMD_DOMAIN/BASE_URL, NOT vmtraefik-proxy (external bridge) — all web containers must join~/go/bin/crane (NOT on PATH)docker compose (plugin at ~/.docker/cli-plugins/). Must cd into service dir — -f flag brokenPort 80 → Traefik ──┬── / → Homepage (dashboard)
├── /hedgedoc → HedgeDoc (:3000) [subpath-aware]
├── /freshrss → FreshRSS (:80)
├── /traefik → Traefik dashboard (api@internal)
└── /<service> → Your new service
Direct ports ───────── :6060 → BookLore [no subpath support]
Config: ~/traefik/traefik.yml — static config
~/traefik/dynamic/<service>.yml — per-service routing
~/homepage/config/services.yaml — dashboard entries
mkdir -p ~/docker/<service>/{data,config}~/go/bin/crane pull <image>:<tag> /tmp/<name>.tardocker load -i /tmp/<name>.tar~/docker/<service>/docker-compose.yml → cd ~/docker/<service> && docker compose up -d~/traefik/dynamic/<service>.yml (auto-reloads)~/homepage/config/services.yaml + group in settings.yamlcurl -sI --noproxy '*' http://localhost/<service>Always curl-test links before hardcoding them. Do not assume a route works — prove it.
# 1. Test container responds directly (find internal IP or use exposed port)
curl -sI --noproxy '*' http://127.0.0.1:<host-port>/
# 2. Test Traefik route works (after writing dynamic config, before Homepage)
curl -sI --noproxy '*' http://127.0.0.1/<service>/
# 3. Test subpath: check HTML AND assets (not just the first response)
curl -s --noproxy '*' http://127.0.0.1/<service>/ | grep -E '<base href|<script src|<link.*href'
# If asset paths are absolute (e.g. /styles.css not ./<service>/styles.css) → subpath won't work
# 4. Test Homepage href URL resolves (the exact URL that will go in services.yaml)
curl -sI --noproxy '*' <href-value>
# 5. Test widget URLs (e.g. Traefik widget)
curl -s --noproxy '*' http://traefik:8080/api/overview
Rule: If curl returns 404, 502, or broken assets → fix FIRST, then write the config.
| Gotcha | Detail |
|---|---|
| Container name | Use http://<container>:<port> in Traefik config, NOT localhost |
| Sub-path + stripPrefix | Need BOTH: stripPrefix in Traefik AND app's BASE_URL/CMD_URL_PATH. Test CSS/JS assets, not just HTML. BUT some SPAs (e.g. Booklore) don't support subpath at all — use direct port instead |
| Subpath compatibility | Before deploying behind subpath, check if the app supports it. SPAs with hardcoded <base href="/"> and no BASE_PATH config will break. Use direct host port + Homepage href: http://172.16.252.7:<port> as fallback |
| CMD_DOMAIN must match access IP | For apps like HedgeDoc with CMD_DOMAIN, set it to the IP/hostname users actually use (e.g. 172.16.252.7), NOT vm.local if users access via IP |
| No host ports | Don't expose ports if Traefik handles routing. Exception: apps without subpath support MUST expose host ports |
| Traefik dashboard needs 2 routers | Dashboard at /traefik uses stripPrefix + api@internal. But dashboard JS calls /api/... hardcoded — need a second router PathPrefix(/api) → api@internal (no strip). Without it, API calls fall through to Homepage and dashboard shows empty data. Do NOT use api.basePath — it breaks the insecure port API and the Homepage widget |
| Priority 10 | Set on all routers so Homepage / catch-all still works |
| Auth | auth@file for BasicAuth — omit for public services |
| Volume paths | Always absolute: /home/htlin222/docker/<service>/... |
| Topic | File |
|---|---|
| Templates (compose, traefik, homepage, makefile) | @templates.md |
| Troubleshooting | @troubleshooting.md |
| Reference stacks (ready-to-deploy) | references/*.yml |
| Group | Current Services |
|---|---|
| Media | Booklore (direct port :6060, no subpath support) |
| Productivity | HedgeDoc (subpath via Traefik, CMD_DOMAIN=172.16.252.7) |
| Infrastructure | Traefik |