My work setup for PHP development
Tags: php, productivity
Published: 2024-07-10 11:04:37

---
title: My work setup for PHP development
published: true
description: 
tags: php, productivity
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/if0r9v2pye9o8bhihjai.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-07-04 19:43 +0000
---

These days the majority of my (programming) work is (in order of SLOC): PHP, Javascript (including Node), CSS, HTML, and shell scripts. I do sometimes dip into other languages, but the instances are tiny compared to these main ones.

And this is my story.

## Hardware

I'm writing this on my main me-facing machine. It's running Windows 11, but that's almost entirely for Important Gaming Reasons.

Work provides me with a MacBook Pro, which I need to use for Important Corporate Reasons such as VPN access, and because it has a nicer video meeting experience. But really, I just shell into it and use it as a docker host and network proxy. I don't get along with the Apple keyboard, which is a broken mix of UK ISO and US ANSI and feels like typing on a child's toy. I appreciate the touchpad and screen, which are both impressive - but I much prefer using a mouse. So the Mac is relegated to being a third screen on the corner of my desk.

![A main in a suit carrying too many plain brown paper bags](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7i7b70xe648hnulok41e.jpg)

It's a mixed bag.


I have a laptop I use if I'm working at the kitchen table, which I occasionally do. It's running ChromeOS though I'll probably swap that out for Linux at some point. "Developer" mode in ChromeOS gives me a command line and shell access, so my workflow with browser/cli is pretty much the same.


## Operating system

![John Connor in Terminator 2 saying, "all of them, I think"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu0tf2a6kzm2z33smykj.gif)

Everything I do for work is through Ubuntu under WSL on the Windows 11 desktop, SSH on the ChromeOS laptop or Barrier'd into the MacBook Pro.

I know this sounds impractical. There are weird issues, such as Apple's bug where you can't use an IPv4 address in `/etc/hosts` for external connections because the firewall blocks it but you can if use IPv6, _even if you're not connecting via IPv6_. Oh, there were fun times figuring that hack out.

But though decade-ago me would have never thought it, nowadays Windows Subsystem for Linux - specifically WSL2 - is actually pretty decent. You can even run X applications if you install an X server, and there are a bunch of those available.

I don't use X for anything though. If it's not in a browser, I don't tend to care about it, and there's no good reason to use a Linux browser via X compared to a native one.

I can't help feeling a little bit _dirty_ for using Windows, but I cram that feeling way down inside and try to ignore it.

## Desktop - [Barrier](https://github.com/debauchee/barrier)

I don't use this too much any more, but Barrier is a fork of Synergy from before Synergy went closed-source. It bills itself as a kind-of-software-KVM, but what it boils down to is that I can move my mouse between different computers exactly the same as I can between the pair of monitors on my PC. If I move the mouse off the right side of my desktop monitor, it appears on my Macbook, and all mouse and keyboard input are seamlessly transferred there, just as if it was all one glorious whole.

Hashtag #gamechanger.

## Terminal - [WezTerm](https://wezfurlong.org/wezterm/index.html)

I have only recently started using WezTerm. "Recently" in terminal-speak means in the last year or two, because things move slowly in this world. I don't tend to change unless there's a good reason.

So what was my good reason? What was wrong with Windows Terminal/iTerm 2? Well, WezTerm is cross-platform, and I can share the same configuration - in Lua! - between hosts. It doesn't make weird restrictions (like the way Suckless will never support tabs), and it's very customisable.

As far as customisation goes, it's mostly font, background image and colourscheme. I usually use [Gruvbox](https://github.com/morhetz/gruvbox/wiki/Gallery)[^1] Dark for most things, though I override a couple of bits depending on the context. 

But wait. Background image, you ask? On a terminal? Why? Well, it so happens I have a post about that:

{% embed https://dev.to/moopet/my-one-and-only-terminal-tip-ooa %}

## Shell - zsh

I settled on zsh because it's the default on Macs. I know, I know: I don't really use the Mac much. But it's almost entirely compatible with bash for all the things I care about, and it's available on all the systems I use.

I try to make every script I write POSIX-compliant, and if I use something that's different between BSD and GNU (like `sed -i`) I'll wrap it in a condition.

It's fair to say that the choice of shell doesn't really matter much.

So before you say anything, no, I don't use oh-my-zsh. It doesn't offer me anything I care about that I can't do out-the-box with zsh (or bash for that matter).

Oh, and [I almost never use aliases](https://dev.to/moopet/the-case-against-aliases-2mb1), either.


## Editor - [Neovim](https://neovim.io/)

I've been a Vi/Vim user for a long time, but I switched to neovim a year or two ago. I didn't originally see the point in switching, because all the features people went on about in neovim (and they did oh so go on about them! - async, LSPs, embedded terminals, etc.), well, they were either also available in recent versions of Vim or were stuff I really wasn't interested in. Stuff I didn't think belonged in an editor. Stuff that was trying to make Vim into Emacs.

Well, I still think those same grumpy thoughts, but I decided to try out a few of the neovim "distros" just to see what was out there and have ended up sticking with it. When loaded with plugins, it's certainly buggier than Vim, but it's still also a nice and comfortable editor for me - and it has more of a future, especially now Bram is gone (RIP).

## Productivity

### [Tmux](https://github.com/tmux/tmux/wiki)

Tmux is, as it's always introduced, a "terminal multiplexer", like GNU screen. It lets you close a terminal session and reopen it without losing your work, and it lets you run multiple terminal sessions at the same time.

The upshot of this is that I can leave my work running on the MacBook and connect from other machines via ssh and, by running `tmux attach` I am right back in the thick of things. I don't need to open a bunch of sessions each time, or remember what directory I was in or what services were running, it's all just there.

### [Tmuxinator](https://github.com/tmuxinator/tmuxinator)

The tmuxinator project is a wrapper for tmux, which lets you manage multiple separate tmux sessions.

As an example, here's the list of projects I currently have running on my macbook:

```
❯ tmuxinator ls
tmuxinator projects:
bc           biascan      ec           fabric       gce          ifpma
leith        leith-2023   msgan        chickenland  ngs          ngs-new
ods          ren          renaissance  scramble     sf           sf-cms
sf-forms     sf-myplans   sgh          srn
```

What's in these projects? Well... they have a lot of specifics in them, but what they mostly boil down to is similar to this random project I picked as an example:

```yaml
windows:
  - cms:
    - ddev start
  - storybook:
      panes:
        - watcher:
          - cd web/storybook
          - yarn watch
  - middleware:
    - workon mw8
  - logs:
      panes:
        - cms:
          - workon ngs
          - docker exec -it ngs-cms-php drush -y --uri=ngs-cms.shore.signal.sh -r /shore_site/web ws --tail --full --extended --count=1
        - new-cms:
          - workon ngs-cms-2022
          - docker exec -it ngs-cms-2022-app vendor/drush/drush/drush ws --extended
        - middleware:
          - workon mw8
          - docker exec -it ngs-middleware-app vendor/drush/drush/drush ws --extended
  - build-services:
      panes:
        - new-cms:
          - workon ngs-cms-2022
          - cd web/storybook
          - yarn storybook
```

In this example, I have tmux windows for a Drupal 7 project, its Drupal 10 rebuild, some shared middleware, the front-end build services, a storybook server and a metric ton of logging.


![The ridiculous number of switches and dials in the Concorde cockpit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qscb38nc4uknkctrol4t.jpg)


I can spin this all up with `tmuxinator <project name>`, and switch between its collection of windows with `Ctrl-A <number>` and to any number of completely different projects with a pop-up menu I get by hitting `Ctrl-A S`.

### [Ddev](https://ddev.com)

Ddev is something that lets you create containerised (docker) environments for projects. It works with PHP and Node and (experimentally) Python.


![A small statue of a giraffe standing on a zebra which in turn is standing on an elephant](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8izlytixeun18eup0g4.jpg)

The thing that manages the stack, basically.

My company used to use a home-grown docker-compose wrapper for this, back when there weren't many options. Ddev is really solid, though, and every time I have to work on a legacy or inherited project I'll convert it to Ddev as soon as I check it out. It doesn't usually take very long, and it means we have a consistent way of working. It makes it incredibly quick and easy to switch between PHP or Node versions, for instance.

Some of its main selling points for me are:

* Uses [Mutagen](https://mutagen.io/) for the file system, so it's fast even on MacOS (where Docker mounts are notoriously slo-o-ow)
* Easily lets you reconfigure PHP and Node versions
* Knows about a bunch of third-party apps - for instance, if you have a database GUI app like TablePlus or DBeaver you can launch it from the command line
* Supports community-maintained add-ons 

and so on. It's good.

---
Image credits:
"Man Carrrying Groceries" - [DodgertonSkillhause](https://morguefile.com/p/1001058)
"The Ridiculous Switcherama of the Concorde Cockpit" - Me.
"Statue" - [lauramusikanski](https://morguefile.com/p/1070446)
"Scene from Terminator 2" - Sorry, I can't hear you I'm going through a tunnel

[^1]: I pronounce it the way it's spelt.