You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Projects use a **Docker Compose overrides** pattern: a base `docker-compose.yml` merged with `docker-compose.dev.yml` (local) or `docker-compose.prod.yml` (production).
8
+
- Projects use a **Docker Compose overrides** pattern: a base `docker-compose.yml` merged with `docker-compose.$SPIN_ENV.yml`. `SPIN_ENV` defaults to `dev` (→ `docker-compose.dev.yml`). Common values: `dev`, `ci`, `prod`.
- In Docker, services connect via container name as hostname (`DB_HOST=mysql`, `REDIS_HOST=redis`), not `localhost`.
13
12
14
13
## Essential commands
@@ -17,14 +16,54 @@
17
16
|---------|---------|
18
17
| `spin up` | Start development environment (foreground) |
19
18
| `spin up --build` | Start and rebuild containers (recommended default if custom Dockerfile is used) |
20
-
| `spin run <service> <cmd>` | Run a one-off command in a new container |
21
-
| `spin exec <service> <cmd>` | Run a command in a running container |
19
+
| `spin exec <service> <cmd>` | Run a command in a running container (reuses live container, near-instant) |
20
+
| `spin run <service> <cmd>` | Run a one-off command in a new container (use when the stack is not running) |
22
21
| `spin deploy <env>` | Deploy to a provisioned server |
23
22
| `spin provision` | Provision and configure servers |
24
23
24
+
### `spin exec` vs `spin run`
25
+
26
+
- **`spin exec`** — use when the stack is running. Reuses the live container. This is the right default for `artisan`, `composer`, `npm`, tests, and ad-hoc commands during development.
27
+
- **`spin run`** — use when the stack is not running, or when a fresh container with different env vars or isolated state is needed. Creates (and removes) a new container each invocation.
28
+
29
+
### The `-T` flag (disable pseudo-TTY)
30
+
31
+
Compose auto-detects TTY by default, so interactive use from a terminal usually works without `-T`. **In AI agent, CI, and other subprocess contexts**, that auto-detection can misfire — Compose sees a TTY on stdin while downstream output is being captured, which can cause hangs, ANSI-garbled output, or prompts with nowhere to respond.
32
+
33
+
Pass `-T` as a defensive default when running commands from an AI agent, CI pipeline, or any wrapper script:
34
+
35
+
```bash
36
+
./vendor/bin/spin exec -T php php artisan test
37
+
./vendor/bin/spin run -T php composer install
38
+
```
39
+
40
+
Omit `-T` when interactivity is actually needed (`artisan tinker` without `--execute`, interactive `make:*` prompts, `spin exec php bash`).
41
+
42
+
### Running Laravel tests
43
+
44
+
Prefer the **already-running dev stack** — it's faster than spinning up a parallel CI stack:
45
+
46
+
```bash
47
+
./vendor/bin/spin exec -T php php artisan test
48
+
./vendor/bin/spin exec -T php php artisan test --filter=ExampleTest
49
+
```
50
+
51
+
`php artisan test` works for both PHPUnit and Pest. If the project exposes a `composer test` script, prefer that via `spin exec -T php composer test`.
52
+
53
+
**Before assuming the dev stack is enough, inspect the test config** (`phpunit.xml`, `phpunit.xml.dist`, or `phpunit.dist.xml`):
54
+
55
+
- If `<php>` overrides `DB_CONNECTION` to `sqlite` with `DB_DATABASE=:memory:` (and `CACHE_STORE`/`QUEUE_CONNECTION`/`SESSION_DRIVER` set to `array`/`sync`), tests are self-contained — the dev stack is plenty.
56
+
- If the test config uses the real database/cache services, the dev stack usually still works. Reach for `SPIN_ENV=ci` only when CI parity is needed (reproducing a CI-only failure, matching exact service versions, dry-running the pipeline). See the **spin-laravel-development** skill's `TESTING.md` for the full CI-parity workflow.
57
+
25
58
## When to activate the full skill
26
59
27
-
For tasks involving Docker Compose configuration, Dockerfile changes, `serversideup/php` image settings, adding Laravel services (databases, queues, Horizon, Reverb), server provisioning, deployment, or troubleshooting containerized environments — activate the **spin-laravel-development** skill.
60
+
Activate the **spin-laravel-development** skill for tasks involving:
61
+
- Docker Compose configuration or Dockerfile changes
- Running multiple Compose environments in parallel
66
+
- Server provisioning, deployment, or troubleshooting containerized environments
28
67
29
68
## Laravel Boost MCP setup
30
69
@@ -44,7 +83,20 @@
44
83
spin run php php artisan boost:install
45
84
```
46
85
47
-
**IMPORTANT:** `spin-mcp-wait.sh` is exclusively for MCP server startup. NEVER use it to run commands. Always use `spin run` or `spin exec` for running commands (e.g., `spin run php composer install`).
86
+
**IMPORTANT:** `spin-mcp-wait.sh` is exclusively for MCP server startup. NEVER use it to run commands. Always invoke `spin exec` (running stack) or `spin run` (stopped stack) directly.
87
+
88
+
If this error appears, drop `spin-mcp-wait.sh` and invoke `spin` directly:
89
+
90
+
```
91
+
Error: spin-mcp-wait.sh is only for starting the MCP server. Use 'spin' directly instead.
Copy file name to clipboardExpand all lines: resources/boost/skills/spin-laravel-development/COMMANDS.md
+17-3Lines changed: 17 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,15 +73,21 @@ Examples:
73
73
```bash
74
74
spin run php composer install
75
75
spin run php php artisan migrate
76
-
spin run node yarn install
76
+
spin run node npm install
77
+
spin run -T php composer install # Defensive -T for AI/CI/subprocess contexts
77
78
```
78
79
79
80
Spin-specific options:
80
81
-`--skip-pull` — Do not automatically pull images
81
82
-`--force-pull` — Pull images regardless of cache
82
83
84
+
Key Docker Compose options:
85
+
-`-T` — Disable pseudo-TTY allocation. Compose auto-detects TTY by default, so terminal use works without it. Pass `-T` as a defensive default when invoking from an AI agent, CI pipeline, or subprocess — auto-detection can misfire there and cause hangs or garbled output.
86
+
83
87
The container is automatically removed after the command completes. Container dependencies are not started.
84
88
89
+
Use `spin run` when the stack is not running or when isolated state / different env vars are needed. If the stack is already running, prefer `spin exec` — it reuses the live container and is near-instant.
90
+
85
91
### `spin exec`
86
92
87
93
Run a command in a **currently running** container (requires `spin up` to be active).
@@ -90,12 +96,20 @@ Run a command in a **currently running** container (requires `spin up` to be act
-`-T` — Disable pseudo-TTY allocation. Compose auto-detects TTY by default, so terminal use works without it. Pass `-T` as a defensive default when invoking from an AI agent, CI pipeline, or subprocess — auto-detection can misfire there, causing hangs, ANSI-garbled output, or prompts with nowhere to respond.
110
+
111
+
`spin exec` is the default choice for `artisan`, `composer`, `npm`, and ad-hoc commands during active development.
Copy file name to clipboardExpand all lines: resources/boost/skills/spin-laravel-development/SKILL.md
+55-14Lines changed: 55 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
name: spin-laravel-development
3
-
description: "Developsand deploys Laravel applications using Spin and serversideup/php Docker images. Covers Docker Compose configuration, development environment setup, container commands, Laravel service configuration (databases, queues, Horizon, Reverb), server provisioning, and deployment workflows. Use when working with Spin, Docker Compose files, serversideup/php images, spin commands, configuring Laravel services in Docker, or deploying Laravel apps to production servers."
3
+
description: "Develops, tests, and deploys Laravel applications using Spin and serversideup/php Docker images. Covers Docker Compose configuration, development environment setup, container commands, running Laravel tests (PHPUnit and Pest), SPIN_ENV selection and CI parity, parallel Compose environments, Laravel service configuration (databases, queues, Horizon, Reverb), server provisioning, and deployment workflows. Use when working with Spin, Docker Compose files, serversideup/php images, spin commands, running artisan test, configuring Laravel services in Docker, or deploying Laravel apps to production servers."
4
4
---
5
5
6
6
# Spin Laravel Development
@@ -13,6 +13,7 @@ description: "Develops and deploys Laravel applications using Spin and serversid
@@ -24,7 +25,8 @@ description: "Develops and deploys Laravel applications using Spin and serversid
24
25
25
26
-**NEVER** run commands that could destroy data without explicitly confirming with the user first. This includes `docker system prune`, `docker volume rm`, dropping databases, removing services, or any destructive operation.
26
27
- If Spin fails to run, it is likely because Docker Desktop is not started. Check with `docker info`. If Docker is not running, tell the user to start Docker Desktop and offer to retry before continuing.
27
-
- Always prefer `spin run` over `spin exec` for one-off commands — it is safer because it creates an isolated container.
28
+
- Prefer `spin exec <service> <cmd>` when the stack is running — it reuses the live container and is near-instant. Use `spin run` when the stack is not running or isolated state is needed.
29
+
- Pass `-T` as a defensive default when invoking commands from an AI agent, CI, or subprocess context. Compose auto-detects TTY in regular terminals, but that detection can misfire when wrapped, causing hangs or garbled output.
28
30
29
31
## Laravel Boost MCP
30
32
@@ -38,12 +40,18 @@ BOOST_COMPOSER_EXECUTABLE_PATH="./vendor/bin/spin run php composer"
38
40
BOOST_NPM_EXECUTABLE_PATH="./vendor/bin/spin run node npm"
39
41
```
40
42
41
-
**NEVER use `spin-mcp-wait.sh` to run commands.** It is exclusively for MCP server startup. The script will refuse non-MCP invocations with an error. Always use `spin run` or `spin exec` for running commands:
43
+
**NEVER use `spin-mcp-wait.sh` to run commands.** It is exclusively for MCP server startup. The script will refuse non-MCP invocations with this error:
44
+
45
+
```
46
+
Error: spin-mcp-wait.sh is only for starting the MCP server. Use 'spin' directly instead.
47
+
```
48
+
49
+
If that error appears, drop `spin-mcp-wait.sh` and invoke `spin` directly:
42
50
43
51
```bash
44
-
spin run php composer install# Correct
45
-
spin run php php artisan migrate # Correct
46
-
spin-mcp-wait.sh spin run php ... # WRONG — never do this
Syntax: `spin run<service> <command>` — the first argument is the **service name** from `docker-compose.yml`.
195
+
Syntax: `spin <exec|run> [-T] <service> <command>` — the service argument is the **service name** from `docker-compose.yml`.
188
196
189
197
```bash
190
-
spin run php composer install
191
-
spin run php php artisan migrate # First "php" = service, second "php" = binary
192
-
spin run php php artisan make:model Post
193
-
spin run node yarn install
194
-
spin run node yarn dev
198
+
spin exec php composer install
199
+
spin exec php php artisan migrate # First "php" = service, second "php" = binary
200
+
spin run php php artisan make:model Post
201
+
spin exec node npm install
202
+
spin exec node npm run dev
195
203
```
196
204
197
-
**`run` vs `exec`**: Use `spin run` for one-off commands (creates a new container, runs, exits). Use `spin exec` to execute in an already-running container (requires `spin up` to be active). Prefer `spin run` for package installs, migrations, artisan commands.
205
+
**`exec` vs `run`**:
206
+
207
+
-**`spin exec`** reuses the live container from an already-running stack. Near-instant. Default for `artisan`, `composer`, `npm`, and ad-hoc commands during development.
208
+
-**`spin run`** creates a new container each invocation. Use when the stack is not running, or when isolated state / different env vars are needed.
209
+
210
+
**The `-T` flag**: Compose auto-detects TTY, so interactive terminal usage works without `-T`. Add `-T` as a defensive default when invoking from an AI agent, CI pipeline, or wrapper script — auto-detection can misfire in those contexts, causing hangs or ANSI-garbled output:
See [COMMANDS.md](COMMANDS.md) for the complete 26-command reference.
244
262
263
+
## Running tests
264
+
265
+
Prefer the **already-running dev stack** — it's faster than spinning up a parallel CI stack:
266
+
267
+
```bash
268
+
./vendor/bin/spin exec -T php php artisan test
269
+
./vendor/bin/spin exec -T php php artisan test --filter=ExampleTest
270
+
./vendor/bin/spin exec -T php composer test# If the project exposes a composer test script
271
+
```
272
+
273
+
`php artisan test` works for both PHPUnit and Pest.
274
+
275
+
**Before assuming the dev stack is enough, inspect the test config** (`phpunit.xml`, `phpunit.xml.dist`, or `phpunit.dist.xml`):
276
+
277
+
- If the `<php>` block overrides `DB_CONNECTION` to `sqlite` with `DB_DATABASE=:memory:` (and cache/queue/session set to `array`/`sync`), tests are self-contained — the dev stack is plenty.
278
+
- If the test config uses the real database/cache services, the dev stack usually still works. Reach for `SPIN_ENV=ci` only when CI parity is explicitly needed: reproducing a CI-only failure, matching exact service versions, or dry-running the pipeline before pushing.
279
+
280
+
See [TESTING.md](TESTING.md) for the full CI-parity workflow, parallel Compose environments, and the override-network gotcha.
281
+
245
282
## serversideup/php images
246
283
247
284
Choose the right variant:
@@ -332,6 +369,9 @@ The `.spin.yml` file defines users, providers, servers, and environments. Suppor
332
369
| Stale containers | Use `spin up --build` to rebuild |
333
370
| DB password not working | Credentials are only created on first container init — remove volume to reset |
334
371
| Permission errors in container | Check `SPIN_USER_ID`/`SPIN_GROUP_ID` match host user |
372
+
| Command hangs in AI/CI wrapper | Compose TTY auto-detection misfired — add `-T` to `spin exec`/`spin run` |
373
+
| `SPIN_ENV=ci` clobbered dev containers | `docker-compose.ci.yml` needs its own `name:` project (see [TESTING.md](TESTING.md)) |
374
+
| "host not found" between services on `SPIN_ENV=ci` | Override network didn't include inherited services (see [TESTING.md](TESTING.md)) |
335
375
336
376
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for remote server debugging and Docker Swarm troubleshooting.
337
377
@@ -343,4 +383,5 @@ See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for remote server debugging and Doc
0 commit comments