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!