start-vibing-stacks 2.32.0 → 2.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,312 @@
1
+ ---
2
+ name: kubernetes-patterns
3
+ version: 1.0.0
4
+ description: "Kubernetes 2026 production patterns: Pod Security Standards (restricted), NetworkPolicy default-deny, graceful shutdown with preStop + SIGTERM draining, zero-downtime rolling updates (maxUnavailable:0 + readiness), HPA with custom metrics, PDBs, topology spread, resource QoS, and day-2 readiness checklist. Use when deploying to EKS, GKE, AKS or self-managed clusters."
5
+ ---
6
+
7
+ # Kubernetes Patterns (2026 Production)
8
+
9
+ **Invoke when writing Deployments, Services, NetworkPolicies, HPA, PodDisruptionBudgets, or any workload manifest for production clusters.**
10
+
11
+ > 2026 reality: Pod Security Standards (PSS) + NetworkPolicy default-deny is the baseline. Zero-downtime requires readiness probe + preStop sleep + `maxUnavailable: 0`. Graceful shutdown is mandatory — pods that ignore SIGTERM cause request drops during rollouts and drains.
12
+
13
+ ---
14
+
15
+ ## 1. The Day-2 Readiness Checklist (Non-Negotiable)
16
+
17
+ Every production workload must have:
18
+
19
+ | Control | Why | How |
20
+ |---------|-----|-----|
21
+ | **Readiness probe** | Traffic only reaches healthy pods | `httpGet /readyz` or `exec` |
22
+ | **Liveness probe** | Restart stuck containers | `httpGet /livez` |
23
+ | **Startup probe** (slow apps) | Give slow containers time to boot | `httpGet /startupz` |
24
+ | **Resource requests + limits** | QoS class + scheduling | `requests.memory/cpu`, `limits` |
25
+ | **PodDisruptionBudget** | Survive voluntary disruptions (drains) | `minAvailable: 1` or `maxUnavailable: 1` |
26
+ | **Topology spread** | High availability across zones/nodes | `topologySpreadConstraints` |
27
+ | **SecurityContext** | Non-root + read-only + drop ALL | See §Security |
28
+ | **NetworkPolicy** | Default-deny + explicit allow | See §NetworkPolicy |
29
+ | **Graceful shutdown** | Drain in-flight requests on SIGTERM | `preStop` + handler |
30
+ | **Rolling update strategy** | Zero downtime | `maxUnavailable: 0`, `maxSurge: 1` |
31
+
32
+ ---
33
+
34
+ ## 2. Zero-Downtime Rolling Update (The 2026 Pattern)
35
+
36
+ ```yaml
37
+ apiVersion: apps/v1
38
+ kind: Deployment
39
+ metadata:
40
+ name: api
41
+ namespace: production
42
+ spec:
43
+ replicas: 3
44
+ strategy:
45
+ type: RollingUpdate
46
+ rollingUpdate:
47
+ maxUnavailable: 0 # Never drop below desired replicas
48
+ maxSurge: 1 # Add one extra pod during rollout
49
+ minReadySeconds: 10 # Wait before marking new pod "ready"
50
+ selector:
51
+ matchLabels:
52
+ app: api
53
+ template:
54
+ metadata:
55
+ labels:
56
+ app: api
57
+ spec:
58
+ terminationGracePeriodSeconds: 45 # > preStop sleep + longest request
59
+ containers:
60
+ - name: api
61
+ image: myorg/api:v1.2.3
62
+ ports:
63
+ - containerPort: 3000
64
+ readinessProbe:
65
+ httpGet:
66
+ path: /readyz
67
+ port: 3000
68
+ initialDelaySeconds: 5
69
+ periodSeconds: 5
70
+ failureThreshold: 3
71
+ livenessProbe:
72
+ httpGet:
73
+ path: /livez
74
+ port: 3000
75
+ initialDelaySeconds: 15
76
+ periodSeconds: 10
77
+ failureThreshold: 3
78
+ lifecycle:
79
+ preStop:
80
+ exec:
81
+ command: ["sh", "-c", "sleep 10"] # Give kube-proxy time to remove endpoint
82
+ resources:
83
+ requests:
84
+ memory: "256Mi"
85
+ cpu: "250m"
86
+ limits:
87
+ memory: "512Mi"
88
+ cpu: "500m"
89
+ ```
90
+
91
+ **Why the preStop sleep?**
92
+
93
+ When a pod is deleted, Kubernetes removes it from Endpoints **asynchronously**. For a few seconds, traffic can still arrive at a `Terminating` pod. The `sleep 10` in `preStop` delays SIGTERM long enough for endpoint propagation to finish.
94
+
95
+ ---
96
+
97
+ ## 3. Graceful Shutdown in Code (Node.js / Python / PHP)
98
+
99
+ Your application **must** handle `SIGTERM` and stop accepting new connections + drain in-flight requests.
100
+
101
+ ### Node.js (Express / Fastify)
102
+
103
+ ```ts
104
+ const server = app.listen(3000);
105
+
106
+ process.on('SIGTERM', () => {
107
+ server.close(() => {
108
+ // Close DB connections, flush logs, etc.
109
+ process.exit(0);
110
+ });
111
+ });
112
+ ```
113
+
114
+ ### Python (FastAPI / Uvicorn)
115
+
116
+ ```python
117
+ import signal
118
+ import sys
119
+ from contextlib import asynccontextmanager
120
+
121
+ @asynccontextmanager
122
+ async def lifespan(app: FastAPI):
123
+ yield
124
+ # Cleanup on shutdown
125
+ await db.disconnect()
126
+
127
+ app = FastAPI(lifespan=lifespan)
128
+
129
+ def handle_sigterm(signum, frame):
130
+ sys.exit(0)
131
+
132
+ signal.signal(signal.SIGTERM, handle_sigterm)
133
+ ```
134
+
135
+ ### PHP (Laravel Octane / FrankenPHP)
136
+
137
+ Laravel Octane already handles graceful shutdown. Just make sure your services are stateless between requests (see `laravel-octane-inertia` skill).
138
+
139
+ ---
140
+
141
+ ## 4. Pod Security Standards (Restricted Profile)
142
+
143
+ Apply at namespace level:
144
+
145
+ ```yaml
146
+ apiVersion: v1
147
+ kind: Namespace
148
+ metadata:
149
+ name: production
150
+ labels:
151
+ pod-security.kubernetes.io/enforce: restricted
152
+ pod-security.kubernetes.io/audit: restricted
153
+ pod-security.kubernetes.io/warn: restricted
154
+ ```
155
+
156
+ **What `restricted` enforces:**
157
+
158
+ - No privileged containers
159
+ - No hostNetwork / hostPID / hostIPC
160
+ - No hostPath volumes
161
+ - Must run as non-root (`runAsNonRoot: true`)
162
+ - Must drop ALL capabilities
163
+ - `readOnlyRootFilesystem: true` (recommended)
164
+ - `allowPrivilegeEscalation: false`
165
+
166
+ ---
167
+
168
+ ## 5. NetworkPolicy — Default Deny + Explicit Allow
169
+
170
+ ```yaml
171
+ apiVersion: networking.k8s.io/v1
172
+ kind: NetworkPolicy
173
+ metadata:
174
+ name: default-deny-all
175
+ namespace: production
176
+ spec:
177
+ podSelector: {}
178
+ policyTypes:
179
+ - Ingress
180
+ - Egress
181
+ ---
182
+ apiVersion: networking.k8s.io/v1
183
+ kind: NetworkPolicy
184
+ metadata:
185
+ name: allow-api
186
+ namespace: production
187
+ spec:
188
+ podSelector:
189
+ matchLabels:
190
+ app: api
191
+ policyTypes:
192
+ - Ingress
193
+ - Egress
194
+ ingress:
195
+ - from:
196
+ - namespaceSelector:
197
+ matchLabels:
198
+ name: ingress-nginx
199
+ ports:
200
+ - protocol: TCP
201
+ port: 3000
202
+ egress:
203
+ - to:
204
+ - podSelector:
205
+ matchLabels:
206
+ app: postgres
207
+ ports:
208
+ - protocol: TCP
209
+ port: 5432
210
+ - to: [] # Allow DNS egress
211
+ ports:
212
+ - protocol: UDP
213
+ port: 53
214
+ ```
215
+
216
+ ---
217
+
218
+ ## 6. HorizontalPodAutoscaler + PodDisruptionBudget
219
+
220
+ ```yaml
221
+ apiVersion: autoscaling/v2
222
+ kind: HorizontalPodAutoscaler
223
+ metadata:
224
+ name: api
225
+ namespace: production
226
+ spec:
227
+ scaleTargetRef:
228
+ apiVersion: apps/v1
229
+ kind: Deployment
230
+ name: api
231
+ minReplicas: 3
232
+ maxReplicas: 20
233
+ metrics:
234
+ - type: Resource
235
+ resource:
236
+ name: cpu
237
+ target:
238
+ type: Utilization
239
+ averageUtilization: 60
240
+ - type: Pods
241
+ pods:
242
+ metric:
243
+ name: http_requests_per_second
244
+ target:
245
+ type: AverageValue
246
+ averageValue: "1000"
247
+ ---
248
+ apiVersion: policy/v1
249
+ kind: PodDisruptionBudget
250
+ metadata:
251
+ name: api
252
+ namespace: production
253
+ spec:
254
+ minAvailable: 2
255
+ selector:
256
+ matchLabels:
257
+ app: api
258
+ ```
259
+
260
+ ---
261
+
262
+ ## 7. SecurityContext (Every Pod)
263
+
264
+ ```yaml
265
+ securityContext:
266
+ runAsNonRoot: true
267
+ runAsUser: 10001
268
+ runAsGroup: 10001
269
+ fsGroup: 10001
270
+ seccompProfile:
271
+ type: RuntimeDefault
272
+ containers:
273
+ - name: app
274
+ securityContext:
275
+ allowPrivilegeEscalation: false
276
+ readOnlyRootFilesystem: true
277
+ capabilities:
278
+ drop: ["ALL"]
279
+ ```
280
+
281
+ ---
282
+
283
+ ## FORBIDDEN
284
+
285
+ | Pattern | Reason |
286
+ |---------|--------|
287
+ | `maxUnavailable: 1` on user-facing services | Drops capacity during rollout |
288
+ | No readiness probe | Traffic can hit pods that are still starting |
289
+ | Ignoring SIGTERM | Requests dropped during drains/rollouts |
290
+ | `runAsUser: 0` or `privileged: true` | Container escape risk |
291
+ | No NetworkPolicy | Lateral movement after compromise |
292
+ | `latest` tag | Unreproducible, hard to rollback |
293
+ | No resource limits | Noisy neighbor + OOMKills |
294
+
295
+ ---
296
+
297
+ ## See Also
298
+
299
+ - `podman-patterns` — rootless local development that mirrors production security posture
300
+ - `docker-patterns` — building the images that run on Kubernetes
301
+ - `secrets-management` — how to mount secrets without baking them into images
302
+ - `ci-pipelines` — GitOps deployment patterns with Argo CD / Flux
303
+
304
+ ---
305
+
306
+ ## Memory Optimization Trigger
307
+
308
+ If this skill grows beyond ~300 lines or accumulates many near-duplicate Deployment examples, run:
309
+
310
+ ```bash
311
+ npx start-vibing-stacks memory optimize --dry-run
312
+ ```
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: laravel-octane-inertia
3
+ version: 1.0.0
4
+ description: "Laravel 12 + Octane (FrankenPHP/Swoole) + Inertia.js + React 19 production patterns for 2026. Covers stateless architecture, worker recycling (--max-requests), scoped bindings, Octane::concurrently(), Inertia SSR, React Server Components inside Inertia pages, queue integration with Horizon, and FrankenPHP as the recommended driver."
5
+ ---
6
+
7
+ # Laravel 12 + Octane + Inertia + React 19 (2026)
8
+
9
+ **Invoke when building high-performance Laravel applications with Inertia + React frontend and Octane workers.**
10
+
11
+ > 2026 reality: **FrankenPHP is the recommended Octane driver** for most teams. Octane gives 5-10x throughput, but requires strict stateless code. Inertia + React 19 lets you build SPA-like UX without maintaining a separate API layer.
12
+
13
+ ---
14
+
15
+ ## 1. Octane Mental Model
16
+
17
+ Octane boots Laravel **once** and reuses the application instance across thousands of requests.
18
+
19
+ **Consequences:**
20
+
21
+ - Singletons and static properties live forever in the worker.
22
+ - Request-scoped data must be re-created on every request.
23
+ - Memory leaks accumulate until the worker is recycled.
24
+
25
+ **Rule:** Treat every request as if it were the first request the worker has ever seen.
26
+
27
+ ---
28
+
29
+ ## 2. Stateless Architecture Rules
30
+
31
+ ### Never do this
32
+
33
+ ```php
34
+ // Bad — lives in memory forever
35
+ private static $user;
36
+
37
+ public function __construct()
38
+ {
39
+ self::$user = auth()->user(); // captured once
40
+ }
41
+ ```
42
+
43
+ ### Do this instead
44
+
45
+ ```php
46
+ // Good — resolved at runtime
47
+ public function handle(Request $request)
48
+ {
49
+ $user = $request->user(); // fresh on every request
50
+ // or
51
+ $user = app('auth')->user();
52
+ }
53
+ ```
54
+
55
+ ### Use scoped bindings for request-scoped services
56
+
57
+ ```php
58
+ // AppServiceProvider
59
+ $this->app->scoped(ExpensiveService::class, function () {
60
+ return new ExpensiveService(...);
61
+ });
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 3. Worker Recycling (`--max-requests`)
67
+
68
+ Always set a recycle limit:
69
+
70
+ ```bash
71
+ php artisan octane:start --server=frankenphp --max-requests=1000
72
+ ```
73
+
74
+ This forces workers to die after 1000 requests, releasing any leaked memory.
75
+
76
+ ---
77
+
78
+ ## 4. Inertia + React 19 (No Separate API)
79
+
80
+ Inertia lets you use Laravel routes + controllers while rendering React components.
81
+
82
+ ```php
83
+ // routes/web.php
84
+ Route::get('/dashboard', function () {
85
+ return Inertia::render('Dashboard', [
86
+ 'user' => auth()->user(),
87
+ 'posts' => Post::with('author')->latest()->take(10)->get(),
88
+ ]);
89
+ });
90
+ ```
91
+
92
+ ```tsx
93
+ // resources/js/Pages/Dashboard.tsx (React 19 Server Component inside Inertia)
94
+ export default function Dashboard({ user, posts }: PageProps) {
95
+ return (
96
+ <div>
97
+ <h1>Welcome, {user.name}</h1>
98
+ <PostList posts={posts} />
99
+ </div>
100
+ );
101
+ }
102
+ ```
103
+
104
+ Inertia handles the SSR + hydration automatically.
105
+
106
+ ---
107
+
108
+ ## 5. React Server Components inside Inertia
109
+
110
+ You can use React Server Components inside Inertia pages (Next.js-style data fetching).
111
+
112
+ ```tsx
113
+ // resources/js/Pages/Posts/Show.tsx
114
+ import { getPost } from '@/actions/posts';
115
+
116
+ export default async function Show({ id }: { id: number }) {
117
+ const post = await getPost(id); // runs on the server
118
+
119
+ return (
120
+ <article>
121
+ <h1>{post.title}</h1>
122
+ <Content>{post.body}</Content>
123
+ </article>
124
+ );
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## 6. Concurrent Tasks with `Octane::concurrently()`
131
+
132
+ ```php
133
+ use Laravel\Octane\Facades\Octane;
134
+
135
+ [$user, $posts, $notifications] = Octane::concurrently([
136
+ fn () => User::find($id),
137
+ fn () => Post::where('user_id', $id)->get(),
138
+ fn () => Notification::where('user_id', $id)->get(),
139
+ ], 5000); // 5 second timeout
140
+ ```
141
+
142
+ This runs the closures in parallel using Swoole/RoadRunner task workers.
143
+
144
+ ---
145
+
146
+ ## 7. Queues + Horizon (Move Heavy Work Out of Workers)
147
+
148
+ Anything that takes > 200ms should be queued.
149
+
150
+ ```php
151
+ // In a controller or action
152
+ dispatch(new ProcessVideo($video))->onQueue('videos');
153
+ ```
154
+
155
+ Monitor with Horizon:
156
+
157
+ ```bash
158
+ php artisan horizon
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 8. FrankenPHP vs Swoole vs RoadRunner (2026 Recommendation)
164
+
165
+ | Driver | Ease of use | Performance | Production maturity | Recommendation |
166
+ |--------|-------------|-------------|---------------------|----------------|
167
+ | **FrankenPHP** | Highest | Excellent | Very high (Caddy-based) | **Default choice** |
168
+ | Swoole | Medium | Highest | High | When you need extreme concurrency |
169
+ | RoadRunner | Medium | Very high | High | When you prefer Go-based workers |
170
+
171
+ **Recommendation:** Start with FrankenPHP unless you have a specific reason not to.
172
+
173
+ ---
174
+
175
+ ## 9. Production Docker + Octane Checklist
176
+
177
+ - Use multi-stage build (see `docker-patterns`)
178
+ - Run as non-root (`www-data` or `10001`)
179
+ - Set `--max-requests=1000`
180
+ - Enable OPcache with `opcache.validate_timestamps=0` and `opcache.jit=tracing`
181
+ - Use `readOnlyRootFilesystem: true` + `emptyDir` for `/tmp` and `storage/framework/cache`
182
+ - Healthcheck on `/healthz`
183
+
184
+ ---
185
+
186
+ ## FORBIDDEN
187
+
188
+ | Pattern | Reason |
189
+ |---------|--------|
190
+ | Storing request data in singletons or static properties | Leaks between users |
191
+ | Using `Date::now()` or `Carbon::now()` in service constructors | Frozen time across requests |
192
+ | Not setting `--max-requests` | Memory leaks eventually OOM the worker |
193
+ | Heavy work inside Octane workers | Blocks the event loop |
194
+ | Passing Eloquent models with relations into Inertia props without `only()` | N+1 queries + bloated payloads |
195
+
196
+ ---
197
+
198
+ ## See Also
199
+
200
+ - `laravel-api-architecture` — controller / form request / policy / resource structure
201
+ - `docker-patterns` / `podman-patterns` — containerizing Octane apps
202
+ - `task-queues` — Horizon patterns (when implemented)
203
+ - Official Laravel Octane docs
204
+
205
+ ---
206
+
207
+ ## Memory Optimization Trigger
208
+
209
+ If this skill grows beyond ~250 lines or accumulates duplicate Octane configuration examples, run:
210
+
211
+ ```bash
212
+ npx start-vibing-stacks memory optimize --dry-run
213
+ ```