I used to be quite adamant about running nearly the same exact software stack locally as I did on my servers. Running Linux made it easy to pull this off and being able to do the same on OS X was a contingency for switching. I have never been a fan of developing inside of a virtual machine and have been reluctant to adopt the use of a virtual development environment for the most part. I would run Apache or Nginx and use the same configuration as I did on production.
It was easy, I rarely ran into issues and I felt the setup was trivial, Now, working with Node.js full-time while still maintaining my older PHP sites, the friction has begun to set in.
The biggest issue thus far has been needing to shut down Nginx before I can run
another project’s grunt
task that binds to port 80. Sure, I could just start
running Nginx on another port, but that would only solve one of my problems.
The other problem is that since I moved away from Apache to Nginx, I no longer
have a simple .htaccess
file that I can edit on the fly. Any new rewrites I
introduce that are too complex for my baked in assumptions requires me to
restart/reload Nginx on production. This is also a trivial task and rarely
comes up, but it really got me thinking about how I solve both of these issues.
I work on projects that are in different languages. Node.js and PHP as I mentioned before, but also Meteor and Jekyll. When I first started to play with Jekyll when I was migrating my blogs away from Wordpress, I really didn’t care for starting Jekyll up and then viewing my site on port 3000 or whatever. It felt really cheap and I associated that workflow with an incompetence towards setting up a web server locally.
Fortunately for those people, we live in an age where the platform can be the service and you can get by with never knowing how to configure and run an actual web server. That’s just not for me, hence feeling like a lack of those skills was a bad thing.
A few years later, this process started to feel more comfortable. Start the server, make some changes, kill the server. Repeat! It’s a bit more manual of a process, but it’s opened my eyes to how I could improve the way I work. Right out of the gate, by running these local servers, there’s no more competing for port 80. Either a project is using it, or it’s been killed.
Further still, you could always bind to another port for each project. Remember kids, using port 80 on OS X means you have to run it as a superuser which kinda fucks up the convenience of starting things up at boot. I can now cross off “start Nginx manually after a reboot” as well!
Another thing I’ve always been adamantly against is manually defining routes in my code. Just has never been my thing. I like to have a set of assumptions on where routes should go and then define anything more complex in my web server’s configuration. This worked out quite well for ages but as mentioned, this requires a reload of Nginx each time a new route gets defined.
Backpedalling a bit, I’ve really grown tired of needing to restart Nginx each time I add something to the config. Fortunately, it’s a pretty rare occurrence but it does mean that any project that I have that rely on that configuration must continue to run on Nginx locally. With that, I am working towards abandoning rewrites in favor of defining routes in my code, thus decoupling my code from any particular web server.
Not relying on a particular web server gives me the flexibility to be able to switch servers down the road if the need arises. It also means that there is even less overhead to setup a local development environment.
Ease of setup for a local development setup was a requirement on my service
HolidayAPI recently. Prior to creating a gulpfile for
the project, you would have to set up Nginx locally. You would have to use the
same path I was already using, link or copy the Nginx configuration to your
local sites-enabled
directory. It was just a very opinionated process to get
a very simple site running locally. I mean, it’s 2 pages for shit’s sake!
With the new site, all you need to do is clone the repository, run a couple of
commands to install the dependencies and then run gulp server
from the root
of the project. Really clean, really simple, fewer steps, zero friction. BOOM!
It’s going to take me a while to get to that point with all of my existing projects but at least I now have a better vision for how I feel a local development environment should work. The fewer the steps and the fewer opinions, the better.
What’s your local development environment looking like these days? Comment below, would love to hear about it!