Docker
When your application runs in Docker, a Docker profile runs snippets inside its container, with the container's PHP, extensions, environment variables, and network. Laravel Sail, Docker Compose projects, and containers in OrbStack or Docker Desktop all work.
Runlet uses the Docker CLI's current context, so it sees the same containers as docker ps in your terminal. It runs code only in containers that are already running: it never starts, stops, or creates your containers.
Creating a Docker Profile
Start your application first (for example, sail up -d or docker compose up -d). Then choose Library ▸ New Docker Profile… (⇧⌘N), also in the target menu.
The left side lists the running containers, with a search field for a name, an image, or a Compose project. Click your application's container: it becomes the profile's container, and the form fills in the name, execution user, working directory, and local source from it. Clicking another container replaces them, except the ones you changed yourself. Then check the form:
| Field | What to enter |
|---|---|
| Name | Shown in the target menu, tabs, and history, such as "Billing API". |
| Working directory | The application's folder inside the container, such as /var/www/html. The menu next to the field suggests the container's working directory and mounts; Browse… lists the container's folders. |
| PHP executable | php, or the path of another PHP inside the container. |
| Execution user | Optional: the user PHP runs as, such as sail or 1000:1000. Empty uses the container's default user. |
| Temporary directory | A writable folder, exported as TMPDIR for each run, so sys_get_temp_dir() works in read-only containers. /tmp by default. |
| Strict types, Mail | As in a local project's options. |
| Local source | The same application's checkout on your Mac. See Local Source. |
| PHP version | The PHP version completion assumes. Empty reads it from composer.json. |
| Environment | Development, staging, or production, and a colour. See Environments & Production. |
| Databases | Database connections you save for this target, for SQL tabs. |
Test Connection runs a short, read-only PHP check inside the container (your snippet doesn't run). It shows the PHP version and binary, the user, whether the working directory exists and is readable, the framework, whether the temporary directory is writable, and how Stop can signal PHP. It also lists application folders it found, each with a Use button.
Two profiles may use the same container, for example with different users or working directories; the form says when another profile uses it.
Saving or opening a profile never runs code. To edit a profile later, choose Edit Docker Profile… in the target menu, or open Library ▸ Manage Profiles…, which shows every Docker and SSH profile side by side.
How Runlet Finds the Container
Containers come and go: docker compose up after a change recreates the container with a new ID. So a profile remembers the container by its Compose project and service, or by its name when it has no Compose labels, never only by its ID.
Before each run, Runlet looks for the container again:
- One running container matches: the run uses it, even when it was recreated.
- Several match (replicas of one service): Runlet asks which one to use.
- A container without Compose labels was replaced by a new one with the same name: Runlet asks before it uses the new one.
- None is running: the run stops and says so. Start the container and run again.
Runlet never switches to another container silently. Right before PHP starts, it checks once more that the container still exists and is running.
Resolve container when opening this profile (in the profile's Connection section) looks for the container as soon as you switch a tab to the profile, so a stopped container shows up before you run. It never runs code.
Local Source
The local source is the application's checkout on your Mac. It's optional, but it powers what Runlet reads from your Mac:
- Completion and diagnostics for your project's classes. Without it, only PHP's own functions and classes complete.
- File links in dumps, errors, and stack traces: paths inside the container map to the local source, and open in your editor.
- Project snippets in
.runlet/snippets/, host commands, Open Project in Editor, and new terminal shells, which start in that folder.
When the profile has no local source and the container's working directory is mounted from a folder on your Mac, Runlet notices: a banner above the editor offers Use for Completion. It's never applied on its own.
Commands and Shells
- Project commands from the Commands panel, and Open REPL, run inside the container, in a terminal tab:
docker exec -it, in the working directory, as the execution user. See Project Commands. - Shell in … Container, in the terminal's + menu, opens a shell in the container's working directory:
bashwhen the container has it, elsesh. - Host commands that a project driver declares run on your Mac, in the local source folder, so
docker composeor your own tools work even while the container is stopped.
Stop
Stop ends the run's PHP process inside the container. Runlet checks that the process belongs to this run before it signals it, sends SIGTERM, and then SIGKILL if PHP doesn't end. The container keeps running: Runlet never uses docker stop.
NOTE
Processes a snippet starts inside a container (with exec() or proc_open()) may keep running after Stop. Stop also needs Linux's /proc, and PHP's posix_kill() or a shell in the container; without them, Runlet reports the stop as unconfirmed.
Settings
Settings ▸ Docker shows whether Docker is running and its version. Leave CLI path empty to find docker on your PATH and in the usual places (Docker Desktop, OrbStack, Rancher Desktop, Homebrew), or choose the binary yourself.
Docker is optional: Runlet needs it only for Docker profiles, and for the Laravel Sandbox when your Mac has no compatible PHP. A Docker container on a server is an SSH profile with a container step.