Setting Up a New Mac for Trellis Development: What Runs on the Host, What Runs in the Lima VM
The question I get most about a Trellis setup is whether you need PHP, Composer, Node and MySQL on your Mac if WordPress runs in a virtual machine anyway. The answer is some of them, and installing the wrong ones is how people end up with a port conflict they cannot explain.
This is how I set up a new Mac for Trellis and Bedrock development, and why each tool is on the host or in the VM.
Two environments
- The host is your Mac. You edit code here, build assets, run Composer and Git.
- The Trellis VM is an Ubuntu machine run by Lima. It runs Nginx, PHP-FPM, MariaDB and WordPress, and matches production.
Your project folder is synced between the two, so you edit on the Mac and the VM sees the change immediately.
| Tool | Host | VM | Why |
|---|---|---|---|
| Trellis CLI | required | no | Manages the VM |
| Composer | required | included | Installs PHP dependencies into vendor/, which syncs to the VM |
| PHP | required | included | On the host it only runs Composer; WordPress runs on the VM’s PHP |
| Node.js | required | no | Runs the Vite dev server with hot reload |
| pnpm | optional | no | Faster alternative to npm |
| MariaDB / MySQL | avoid | included | A host database on port 3306 conflicts with the VM |
| Nginx, PHP-FPM | avoid | included | Only the VM serves the site |
| WP-CLI | optional | included | Run it through trellis vm shell |
So the answer to “do I need duplicate tools” is no. Composer and Node on the host build what the VM serves. The VM does not need Node, because it only serves compiled assets.
Install the tools
# Homebrew, if you do not have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install roots/tap/trellis-cli
brew install composer
brew install php
# Node, through fnm so you can switch versions per project
brew install fnm
fnm install 24
fnm use 24
# Optional
npm install -g pnpm
If you use Laravel Valet you already have PHP, Composer and probably MySQL, and that is fine. The VM is isolated. The only thing to watch is the local database on port 3306, covered below.
SSH key
ssh-keygen -t ed25519 -C "you@example.com"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
cat ~/.ssh/id_ed25519.pub | pbcopy
Add the public key at github.com/settings/keys and test with ssh -T git@github.com. Adding the key to a production server can wait until you need it.
Check everything
trellis --version
composer --version
php --version
node --version
ssh -T git@github.com
If these answer, the machine is ready. The next post clones a project and gets it running.
A normal day
# On the host: dependencies and assets
cd ~/code/your-project/site/web/app/themes/your-theme
pnpm install
pnpm run dev # Vite with hot reload
# In the VM: anything WordPress
trellis vm shell
wp cache flush
Files you save on the Mac appear in the VM, and WordPress serves them with the assets the host built.
When it goes wrong
Port 3306 conflict. Symptom: Ansible playbooks fail with SSH connection errors. A MariaDB or MySQL running on your Mac collides with the VM. Either stop the local server, or run WP-CLI inside the VM and skip the playbooks:
trellis vm shell --workdir /srv/www/your-project.test/current
wp db export /tmp/backup.sql.gz --path=web/wp
wp cache flush --path=web/wp
The VM will not start. Look at what Lima thinks, then delete and rebuild it:
limactl list
trellis vm delete
trellis vm start
trellis provision development
Composer runs out of memory.
php -d memory_limit=-1 $(which composer) install
Set up your Mac differently, or run Trellis without Lima? Find me on Mastodon at @jfrumau@mastodon.social.