Native vs containers
Run PHP locally on Mac without Docker.
Docker is a good tool, and for some teams it's the right one. But for a lot of day-to-day PHP work on a Mac it's a Linux VM you don't need. This page explains how native and container setups actually differ, where each wins, and how Bothy, a native Mac app for PHP and MySQL/MariaDB, works as a Docker alternative for PHP development.
How Docker runs PHP on a Mac
Containers are a Linux feature. macOS can't run them directly, so Docker Desktop (and alternatives such as OrbStack, Colima or Rancher Desktop) starts a Linux virtual machine and runs your containers inside it. The VM gets its own share of CPU and memory.
A typical PHP stack is then a compose.yaml with a PHP-FPM container, a web server container and a database container. Your code lives on the Mac, and is bind-mounted into the VM so the PHP container can see it. That mount is where most of the Mac-specific pain comes from: every file PHP reads crosses the boundary between macOS and the VM.
Docker has improved this a lot. VirtioFS is now the default file-sharing method and is faster than the older gRPC FUSE and osxfs. Docker's "synchronized file shares" go further by keeping a cache inside the VM, but they're only available on the paid Pro, Team and Business plans. An independent benchmark in January 2025 (npm workloads, not PHP) found macOS bind mounts "only 3x slower" than native, down from 5 to 6 times slower in 2023. Better, but not native.
Tools like DDEV and Lando sit on top of Docker and give PHP projects sensible defaults, including Mailpit in DDEV's case. They make Docker far easier to live with; they don't remove the VM.
How a native PHP setup works
A native setup runs the same open-source programs directly on macOS: php-fpm for each PHP version, a web server (Caddy, nginx or Apache), MySQL or MariaDB, and dnsmasq so *.test resolves to your Mac. PHP reads your files straight from the disk, with no VM and no file-sharing layer. Idle services use very little memory, and there's nothing to allocate up front.
You can build this yourself with Homebrew; the guides on installing PHP, multiple PHP versions and local HTTPS show how. Or use a tool that manages it: Laravel Valet, Laravel Herd, MAMP, or Bothy. There's a wider comparison on local PHP development on Mac.
The trade-off is that your Mac isn't your server. macOS PHP is compiled for macOS, the filesystem is case-insensitive by default, and you can't pin the exact Linux image you deploy to.
Native vs Docker for PHP on a Mac
| Native (e.g. Bothy) | Docker / DDEV | |
|---|---|---|
| Runs in | macOS directly | Linux VM |
| File access from macOS | Direct | Bind mount (VirtioFS etc.) |
| Memory when idle | Only running services | VM allocation plus containers |
| Production parity | ◐Partly | ✓Yes |
| Linux-only PHP extensions | -No | ✓Yes |
| Other languages and databases | ◐Partly | ✓Yes |
| Config shared with a team | ◐Partly | ✓Yes |
| Works the same on Linux and Windows | -No | ✓Yes |
| Licence cost | Tool-dependent (Bothy $69 once) | Docker Desktop free for small businesses; paid above that |
"partial" for sharing config: Bothy can export a site with its database dumps and config for another Mac, but it isn't a committed stack definition like a compose file.
When Docker is the right choice
Don't switch for the sake of it. Docker, DDEV or Lando is the better fit if:
Same OS, same PHP build, same extensions and versions as the server. Native can get close, never identical.
PHP next to Python workers, Elasticsearch, PostgreSQL, RabbitMQ… Compose describes them all in one file.
Some PHP extensions and system libraries only build on Linux. A container avoids the fight.
One committed definition that works on Mac, Windows and Linux beats everyone configuring their own machine.
Throwaway environments per branch, or services you don't want on your Mac at all.
Running tests locally in the image your pipeline uses removes a class of surprises.
When native is the better choice
Composer installs, WordPress with lots of plugins, framework caches: no bind mount in the way.
Dozens of sites across several PHP versions, all live at once, without a stack per project.
No VM to allocate. Idle php-fpm pools and a database cost very little.
Docker Desktop needs a paid subscription for businesses with 250+ employees or $10m+ revenue.
Xdebug talks to your editor on localhost, with no host mapping or container networking.
AI assistantsAn agent can create sites, run SQL and read logs through one MCP server, not docker exec.
Docker Desktop licensing, briefly
Docker Desktop is free for personal use, education, non-commercial open source and small businesses, meaning fewer than 250 employees and less than $10 million in annual revenue. Other professional use needs a paid plan. At the time of writing, Pro is $9 a user a month (billed annually), Team $15 and Business $24. Synchronized file shares, the feature that helps most with macOS bind-mount speed, is only on those paid plans.
You don't have to use Docker Desktop to use containers. DDEV's docs list OrbStack (commercial, and which DDEV recommends as the most performant), Lima, Colima and Rancher Desktop as alternatives on macOS. They're worth a look if Docker Desktop's licence is your only objection.
Bothy: a Docker alternative for PHP development
Bothy runs the native setup for you. On first launch it installs PHP from the shivammathur/php tap, MySQL or MariaDB, Caddy and dnsmasq through Homebrew, and runs them as launchd user agents, so they keep running when you quit the app and restart if they crash. Each PHP version gets one php-fpm master and each site its own pool, which is what makes per-site php.ini overrides and per-site FPM stats possible.
What a compose file would give you, Bothy gives you per site: its PHP version, php.ini overrides, environment variables, databases on whichever MySQL or MariaDB server you choose, and Redis, Memcached, Node or Mailpit as add-ons.
- No VM, no bind mounts
- Several MySQL and MariaDB servers side by side
- Services survive quitting the app

Moving a project off Docker
Check first that your project doesn't depend on something only a Linux container provides. Bothy manages Xdebug, Redis and Memcached extensions for you; for anything more unusual, make sure it's available for Homebrew PHP on macOS.
- 1Dump the database from the container
Use your database service's name and credentials from the compose file.
docker compose exec -T db mysqldump -u root -p app > ~/Desktop/app.sql
- 2Stop the containers
Anything publishing ports 80, 443 or 3306 will clash with Bothy.
docker compose down
- 3Add the project as a site
In Bothy, click New Site…, pick the project folder and choose the PHP version your Dockerfile used.
bothy site php app 8.3
- 4Import the database and set the environment
Replace container hostnames such as
dbwith127.0.0.1, port 3306, userroot, no password.bothy db import app ~/Desktop/app.sql bothy site db app assign app bothy site env app APP_ENV local
- 5Recreate the extras
Enable the add-ons your compose file ran as services.
bothy addon enable redis bothy addon php-ext redis 8.3 bothy mail --enable
Questions
It's much better than it was. VirtioFS is now the default, but bind mounts still go through the VM, and one 2025 benchmark measured them at around three times slower than native. Paid Docker plans add synchronized file shares to close more of the gap.
No. Both run natively on macOS with PHP, a web server and MySQL. Laravel Sail and DDEV are Docker options if you want them. See Laravel and WordPress on Bothy.
For personal use, education, non-commercial open source and businesses under 250 employees and $10 million revenue, yes. Larger businesses need a paid subscription.
Yes, as long as containers don't publish ports 80, 443 or the port your Bothy MySQL server uses. Plenty of people use Bothy day to day and Docker for the odd project that needs it.
PostgreSQL, non-PHP runtimes other than Node, Linux-only extensions and a shared compose file. If you need those, stay on Docker for that project.
Sources
Checked September 2026. Details change - check the vendor's site before deciding.