Przejdź do treści
Biblioteka skilli
DevOps i chmura · Automatyzacja

deploy-app

/deploy-app

Wdraża aplikację Laravel opartą na Kickoff przez bin/deploy po SSH, weryfikuje wydanie, sprawdza, jaki commit działa na produkcji, i obsługuje rollback po nieudanym wdrożeniu.

Repozytorium
claude ↗
Licencja
MIT
Ostatnia zmiana repozytorium
27.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
3
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
1
Przestarzałość

Brak sygnałów. Repozytorium zmienione 27.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Wdraża aplikację Laravel opartą na Kickoff przez bin/deploy po SSH, weryfikuje wydanie, sprawdza, jaki commit działa na produkcji, i obsługuje rollback po nieudanym wdrożeniu.

Wyzwalacze z opisu

deploy latestdeploy the apptolong deploydeploy latest dulupush to productionapa commit dekat productionsite down after deploykeluarkan maintenance mode
Oryginalny opis (EN)

Deploys a Kickoff-based Laravel application to its host by running `bin/deploy` over SSH, then verifies the release and knows what each way it can stop means. Use this skill whenever the user asks to deploy an app, push the latest code to production, check what commit production is running, bring a site back up after a failed deploy, or roll back — "deploy latest", "deploy the app", "tolong deploy", "deploy latest dulu", "push to production", "apa commit dekat production", "site down after deploy", "keluarkan maintenance mode", "rollback production", "kenapa 503". Covers the deploy command and

Jak działa

  1. Before anything: establish the target
  2. Deploy
  3. Verify
  4. When it stops
  5. Production traps that have already cost time
  6. Stay in scope
  7. Related
  8. Common Rationalizations
  9. Red Flags
  10. Verification
Sekcje z nagłówków SKILL.md, w oryginale · 182 linii, 1 621 słów
Podgląd SKILL.md
---
name: deploy-app
metadata:
  compatible_agents: [claude-code]
  tags: [deployment, production, ssh, bin-deploy, laravel, kickoff]
description: >
  Deploys a Kickoff-based Laravel application to its host by running `bin/deploy` over SSH,
  then verifies the release and knows what each way it can stop means. Use this skill whenever
  the user asks to deploy an app, push the latest code to production, check what commit
  production is running, bring a site back up after a failed deploy, or roll back — "deploy
  latest", "deploy the app", "tolong deploy", "deploy latest dulu", "push to production", "apa
  commit dekat production", "site down after deploy", "keluarkan maintenance mode", "rollback
  production", "kenapa 503". Covers the deploy command and its flags, the post-deploy
  verification checklist, the recovery path for each failure mode, and the production traps
  that have already cost time. Does NOT cover provisioning a new host from bare metal
  (`bin/provision-host`), CI/CD pipeline design (`ci-cd-pipeline`), or writing deploy
  operations.
---

# Deploy a Kickoff app

One command does the whole release. This skill is mostly about **verifying** it and knowing
which failures matter — a deploy that prints a success line is not the same as a deploy that
worked.

## Before anything: establish the target

Never assume. Confirm these from the project's own docs (`docs/04-deployment/`), its
`CLAUDE.md`, or by asking:

| | |
|---|---|
| Host | SSH target and user |
| Path | application root on the host |
| Domain | public URL, for the health check |
| Branch | what production tracks (usually `main`) |
| Stack | web server, PHP-FPM, supervisor/Horizon, cron (scheduler) |
| Database | engine and whether it is local or managed |

If the project keeps this in a deployment doc, read it once and cache it in your answer — do
not re-derive it every deploy.

## Deploy

Check what would move first, then deploy:

```bash
ssh <user>@<host> 'cd <path> && git fetch origin <branch> --quiet \
  && echo "origin: $(git log --oneline -1 origin/<branch>)" \
  && echo "server: $(git log --oneline -1 HEAD)"'
```

```bash
ssh <user>@<host> 'cd <path> && ./bin/deploy -b <branch> 2>&1 | tail -60'
```

`tail` is deliberate: composer/npm output is long and the last 60 lines contain every decision
point.

> **Gotcha:** Always pass `-b <branch>`. With no `-b`, `bin/deploy` falls back to "latest tag"
> and `git describe` fails outright on a repository that has never been tagged.

What `bin/deploy` does, in order: pre-deploy database dump → `artisan down` → checked
`git checkout`/`pull` → `composer install --no-dev` → `npm ci && npm run build` → clear
config/route/view caches → `migrate --force` → `operations --isolated` → `optimize` →
`horizon:terminate` → chown to the web user → reload PHP-FPM → `artisan up` → health check,
with an **automatic rollback** to the previous commit if the health check does not pass.

## Verify

Always run this afterwards. The script's own success line is not the whole story.

```bash
ssh <user>@<host> 'cd <path> && git rev-parse --short HEAD \
  && php artisan horizon:status \
  && curl -s -o /dev/null -w "login=%{http_code}\n" https://<domain>/login'
```

| Check | Expected |
|---|---|
| `git rev-parse --short HEAD` | matches `origin/<branch>` |
| `horizon:status` | `Horizon is running.` |
| `/login` | `200` |
| deploy output | health check line, all `200` |
| migrations | either `Nothing to migrate` or the list of what ran |

Report the **before/after commit**, whether migrations ran, and the health line. If a migration
ran, name it — CI usually exercises migrations only on SQLite, so the first run against the
production engine is a real event.

## When it stops

| Symptom | What happened | Do this |
|---|---|---|
| `ERROR: could not pull … nothing was deployed` | The guard fired correctly; nothing was touched and `artisan up` already ran. Usually a diverged tree or a transient network failure. | SSH in, `git status`, resolve, re-run. **Never `git reset --hard` without looking first.** |
| `ERROR: deploy operations failed` + site 503 | An `operations/*` file threw. Maintenance mode is left **on deliberately** — a half-applied release must not go live. | Fix the operation and re-run; or `php artisan up` if the effect actually landed. |
| `WARNING: Health check failed` + `Rollback completed to <sha>` | The script already rolled the code back and brought the site up. | Diagnose the failed release. Do **not** re-deploy the same commit blind. |
| Site 503, no deploy running | Left in maintenance mode. | `ssh … 'cd <path> && php artisan up'` |
| `git` "detected dubious ownership" | The tree is chowned to the web user while the deploy runs as root. | `git config --global --add safe.directory <path>` |

> **Gotcha:** **A deploy operation is not a console command.** `Operation` has no `line()`,
> `info()` or `$this->command` — a progress message inside one throws **after** the work it was
> reporting already happened. The effects land, the command reports failure, the deploy stops,
> and production serves 503 over a change that actually succeeded. It also hides on a re-run,
> because by then the loop has nothing left to process and the throwing line is never reached.
> Keep operations silent. This is the single most common cause of the row above.

## Production traps that have already cost time

- **`.env` is not the source of truth for settings the app stores in the database.**
  `App\Settings\MailSettings` overlays `config('mail.*')` at boot, so after any
  `migrate:fresh` the mailer reverts to the seeded default (`log`) — and `app:test-send-mail`
  then exits 0 and writes to `storage/logs` while recording a `mail_histories` row. Nothing
  distinguishes that from a delivered email. Check `config('mail.default')`, never
  `env('MAIL_MAILER')`.
- **Unquoted `.env` values containing spaces break the entire file** ("Failed to parse dotenv
  file") — not just that line. Quote anything with whitespace.
- **Some hosts block outbound SMTP on 25/465/587** (DigitalOcean does). Use **2525**, which
  SparkPost, Mailgun and SendGrid all publish for this reason. It is a network-level block; no
  firewall rule opens it.
- **Any command that may run unattended needs `--force`.** A production confirmation prompt with
  no TTY cancels *and exits 0* — that is how a `migrate:fresh` + seed leaves a migrated but
  **unseeded** database with no superadmin and a caller that believes it succeeded.
- **Never rotate `APP_KEY`.** It destroys every `encrypted:array` column with no recovery, and
  invalidates every registered passkey (`config/passkeys.php` derives the WebAuthn user handle
  secret from it unless `PASSKEYS_USER_HANDLE_SECRET` is pinned).
- **The scheduler must run from cron on exactly one host**, and Horizon supervises only the
  connections named in `config/horizon.php`. A job dispatched with `->onConnection('database')`
  is invisible to a Horizon watching `redis` — it sits unclaimed in `jobs` while the UI reports
  success. Both the scheduler and a worker on the right connection must be alive for the app to
  do anything.
- **A self-hosting deployment platform must never register its own host as a managed node.**
  The destroy path would remove its own runtime; the bootstrap path would rewrite its own SSH
  access.

## Stay in scope

A deploy request is a deploy request. Pre-existing non-fatal warnings in the output —
`optimize` failing at the view stage over a missing Blade component is the classic one, since
views simply run uncached and the site is fine — get **mentioned once** in the report and are
not chased. Do not turn "deploy latest" into a refactor.

## Related

- `docs/04-deployment/` — the project's own host reference, `.env` guide, backup/restore drill
- `bin/provision-host` — idempotent host provisioner for a new machine
- `bin/backup-db` / `bin/backup-app` — run before any risky release
- `ci-cd-pipeline` skill — for the pipeline itself rather than a manual release

---

## Common Rationalizations

| Rationalization | Reality |
|---|---|
| "It's a one-line change, no need for the checklist" | The checklist is short precisely so it survives one-line changes. Most bad deploys were small. |
| "The backup is probably fine" | An unverified backup is not a backup. Check the file size and the timestamp before you migrate. |
| "I'll run the migration and see what happens" | On production, "see what happens" is the plan for data loss. Classify it as additive or destructive first. |
| "Tests passed on main, so this commit is fine" | You are deploying a specific commit. Confirm the suite was green on *that* SHA. |
| "The queue will pick up the new code eventually" | Workers hold the class in memory. Without `queue:restart` they run the old code until they die. |
| "I'll fix forward, rolling back is messy" | Fixing forward under pressure ships a second untested change on top of a broken one. |
| "Maintenance mode is annoying for users" | A 503 for ninety seconds is less annoying than a half-migrated database. |
| "It deployed without errors, so it worked" | A successful deploy command and a working application are different claims. Load a real page. |
| "Let me just rotate APP_KEY to be safe" | That destroys every `encrypted:` column with no recovery, and invalidates every passkey. |

## Red Flags

- Deploying without a fresh, size-checked backup
- A destructive migration with no written rollback
- `migrate:fresh`, `db:wipe`, or `--seed` typed against a production host
- `queue:restart` skipped after a deploy that touched job classes
- New `.env` keys added to the repo but never set on the host
- No post-deploy verification beyond "the command exited 0"
- The app left in maintenance mode with nobody told
- Editing files directly on the production host
- A deploy that also contains a refactor
- `APP_KEY` in the diff

## Verification

- [ ] Backup taken, and its size and timestamp checked
- [ ] Migrations classified; destructive ones have a written rollback
- [ ] Deployed commit SHA matches a green test run
- [ ] `php artisan about` shows the expected env, drivers and versions
- [ ] Homepage and one authenticated route return 200
- [ ] `queue:restart` ran, and one real job was observed completing
- [ ] Scheduler alive on exactly one host; `schedule:list` matches cron
- [ ] Log tailed for 60s with no new exception class
- [ ] App is out of maintenance mode
- [ ] Report delivered: what shipped, what migrated, what warnings were seen and deliberately not chased

---

## Reference Files

| File | Read When |
|---|---|
| `references/deploy-checklist.md` | Running a release — pre-flight, release steps, post-flight verification |
| `references/rollback-playbook.md` | A release went wrong; deciding roll back vs fix forward, and how to do either |
Pliki w paczce (3)
  • SKILL.md 11 KB
  • references/deploy-checklist.md 2 KB
  • references/rollback-playbook.md 2 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · nasrulhazim/claude100MIT
xavieraijon/aijon-labs100MIT
skillsafe/skillsafe-plugin100MIT

Migawka bazy z 13.11.2026 · wersja paczki 2d2f3c410924 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 82ci-cd-pipeline
    Buduje potoki CI/CD dla projektów Laravel: wdrożenia staging i produkcja, Docker, sekrety i powiadomienia o błędach.
  • 95commit-push-deploy
    Commituje zmiany, wypycha je i wdraża tylko na istniejącą, dozwoloną infrastrukturę.
  • 100deploy
    Wdraża przepływ pracy lub agenta Manykind: wydaje sprawdzoną wersję, uruchamia ją na produkcji, cofa zmiany i diagnozuje brakujące wymagania.
  • 100bdb-deploy
    Buduje projekt i wdraża go bezpośrednio na serwer przez rsync po SSH, gdy trzeba wypchnąć build na produkcję bez pełnego potoku CI.
  • 100deploy-frontend-update
    Wdraża zmiany w działającej stronie bezpiecznie: sprawdza build, zapisuje i wysyła zmiany, używa podglądu i pyta przed publikacją na produkcji.
  • 100deploy
    Prowadzi przepływ przed push: lint, typecheck, build i testy, a następnie commit, wydanie i push z wyraźnym potwierdzeniem; uruchamiany tylko ręcznie.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.