One of the first web sites I made was a Geocities-hosted compilation of my highschool friends’ heads photoshopped on animal bodies that I called The Island of Dr. Schmoreau. Because I was fifteen and dumb I thought that showing it to a girl I had a crush on would endear me to her, but instead she immediately burst into tears and stopped talking to me for a week. This was naturally the most devastating thing that had ever happened to poor, misunderstood me. However, once I was able to pick myself up and stop listening to Metallica’s Nothing Else Matters on repeat, I was able to appreciate the lesson that life had handed me: web development is an unprecedented tool for using dark, weird, awkward creativity to sow chaos and madness.
Geocities was a great outlet for creativity because it had a near-instantaneous time to tears (time it took for you to put something you’d made online). If you graduate to making applications, though, it can be confusing and time-consuming to figure out how to deploy them.
Clojure applications are no exception. Do you use Tomcat or a bare uberjar or nginx with a reverse proxy? And heaven help you if you’re new to the world of web apps and don’t even know to ask questions like that. Navigating the modern hosting landscape can take hours, days — fortnights! — making it a serious creative barrier. Sometimes it can be so frustrating that you’ll be tempted to give up and move on to some other project. Chaos: unsown. Madness: uninflicted. Time spent figuring out how to get a Clojure app online could be better spent writing code or sharing your work and getting feedback.
I’ve written this guide because I want you to be able to easily share your work and possibly make your soon-to-be-ex-friends cry. I’ve assumed that you have no experience with deploying an application. By the end, you’ll have the knowledge and tools to get your Clojure web apps online quickly and easily. I’ve also tried to make this tutorial a bit more than a step-by-step, purely practical howto guide; my hope is that you’ll come away with a reasonable foundation in working with servers, and that this will empower you to unleash your creative endeavors (Clojure or otherwise) upon the unsuspecting populace.
You’re also allowed to make money
Twice now I’ve mentioned web app deployment as being part of a larger creative project. If your purpose in getting an app online is to make a giant pile of cash, these tools will still work. They’re completely agnostic to your intentions, your sense of self, your degree of self-actualization, whether you like cats, whether in fact you prefer dogs, the number of times you’ve fallen in love, and your high school GPA. If you’ve found that any of these facets of your life have impacted the functioning of these tools, please file an issue on GitHub.
Once you’ve downloaded a few tools, you’ll only need to run three commands from the command line in order to set up and deploy to a real, hosted Virtual Private Server (VPS); the tools will take care of everything else. They’ll set up a single Ubuntu server by installing nginx, java, and Datomic Free (postgres support is coming soon!). They will copy your application as an uberjar and run it as an Upstart service, and they’ll configure nginx to reverse-proxy requests to the uberjar. (And I will explain what all of that means.)
Disclaimer: This tutorial assumes that you’re comfortable running commands on the command line. If you don’t have much experience with that, Learn Enough Command Line to Be Dangerous is a good, free tutorial. Also, I don’t cover Windows because Ansible, the most important tool we’ll be using, doesn’t work on Windows machines.
In Chapter 1, you’ll clone a fully-functioning example all-Clojure single-page app that uses a Datomic database, and I’ll quickly walk you through how to use some Ansible roles I’ve created to get the application running on a server. You’ll learn how to test your setup on a local virtual machine with Vagrant, and you’ll learn how to deploy to a VPS hosted by Digital Ocean. You’ll get a full serving of what to do with hardly any why it’s being done that way. If you haven’t heard of Ansible or roles or virtual machines, don’t worry: I will explain it all!
(In case you’re wondering, the example application uses ClojureScript for the browser component, relying on Reagent and re-frame (don’t worry if you haven’t heard of those) to render the user interface and send AJAX requests to the backend. The backend uses Ring and Liberator to service the frontend requests.)
Anyway: you’ll get a dose of why the deployment tools work the way they do in Chapter 2, where you’ll be introduced to some basic DevOps concepts. After that, the rest of Chapter 2 is dedicated to teaching you Ansible basics. You’ll work with some example Ansible scripts until you get a good foundation in working with Ansible; the deployment tools consist almost entirely of Ansible scripts.
Chapter 3 is where we go through the scripts line by line so that you’ll understand them as well as if you’d written them yourself, only without all hours of yelling at and shaking your computer like a madman that I went through in putting them together. I’ll start by taking a couple paragraphs to explain the approach I’ve taken in developing the scripts — my philosophy of deployment scripting, if you like abusing words. The goal is for you to be able to customize, debug, and extend them. The scripts are very customizable, but ultimately they’re tailored to my personal needs (hobby apps running on a single Ubuntu server that have real users but that no one depends on for the livelihood), and by the end of this guide I’d like you to be able to use your new tools and knowledge to create something that works for you.
Chapter 3 is also where you’ll learn about the different tools involved (nginx and upstart, for example); you’ll learn about how to use them individually, and how they work together. By learning about these tools from the context of a working web application, you’ll understand them better than if you read tutorials about how to use each tool in isolation. So dark! So powerful!
The deployment scripts were extracted from a really real project I recently released, Community Picks, Community Picks is a site where redditors can share product recommendations for their subreddits. (Anyone can browse, of course!) Definitely check it out! Hopefully it won’t make you cry. At the very least, check out the Clojure section. I’m really hoping it becomes popular, and if you find this tutorial helpful then one way you can express your shadowy appreciation is to check out Community Picks and share it with other people. Thanks a billion!
Tales of Chaos and Madness …From the Shadows
If you ever want to give your spouse a good laugh, take the giant, delicious cinnamon bun that she’s bought from Trader Joe’s and that she’s asked you to save for her. Wait until she leaves for work at her overnight job. Hide most of the cinnamon bun in a cabinet, leaving out only a teeny tiny slice.
When your spouse comes home in the morning and shouts your name, come into the kitchen and tell her that the cinnamon bun was so good. Tell her that you just couldn’t resist, then take the “last piece” and eat it in front of her. Everyone will love it!