Max Krebs

Learning Japanese: Week 1
>>

I don’t remember exactly what day I started really learning Japanese. It was sometime about a week ago. And today I finished learning the first 47 “regular” Hiragana! Not too shabby I don’t think.

It feels like such a cliche, but it was anime that got me into the idea of learning Japanse. I grew up watching anime, but not knowing that is what it was. I watched Dragon Ball Z and Sailor Moon and Gundam Wing and all of the great shows in Toonami. I didn’t know they were from Japan, I just called them my Saturday night cartoons. I remember Naruto and Zatch Bell and the very beginning of One Piece (Sidebar: I remember watching the US premier of One Piece in 2004, an anime that is still running in 2017 when I am writing this). Those memories are some of the happiest I have from my childhood. I still remember watching Princess Mononoke for the first time (I was too young, it was scarring). Then after awhile I just stopped. As I grew out of watching Saturday morning cartoons, I grew out of watching my Saturday Night anime.

Fast forward to the summer after my Freshman year of college. I made a bunch of nerd friends the year before who shared the same anime upbringing that I did. It brought back a lot of nostalgia for those Saturday nights. Over the summer I heard Dodger mention that she was watching an anime called Attack on Titan and that it was the big hit of the season that everyone was talking about. I trusted Dodger’s judgement and started a free trial with Crunchyroll and proceeded to binge Attack on Titan. Back at university, turns out everyone else had been watched Attack on Titan too, and so we started getting together every time a new episode came out and had pizza and snacks. This started my favorite tradition in college. Our friend group kept finding new excuses to get together and watch something each week (we went from Attack on Titan to Legend of Korra to Game of Thrones to a rewatch of Miyazaki movies).

So I slowly got back into anime, and because I didn’t want to wait for the next season of Attack on Titan: manga as well. Shows like Fullmetal Alchemist, SHIROBAKO, Free!, Yuri!!! On Ice became some of my very favorite things. Your Name is probably in my top 5 favorite movies. The more I learned about Japan, the more I loved it.

All that time I wanted to learn Japanese. I came to prefer the subtitled versions of shows and movies, so I wanted to be able to watch without subtitles some day. But everyone I talked to about learning Japanese said it was so hard, so it kind of scared me off.

Until recently when Duolingo added Japanese courses. I used that for around a month before realizing it wasn’t really working for me. But it whet my apetite and now I knew I really wanted to learn.

I came across WaniKani and I liked how they described their approach, but they said I should know all the Hiragana and Katakana before starting. So I went and started the guide they recommended.

A week in, and I feel like I’ve learned more than I did in a month of Duolingo. Sure, I don’t really know any words, but I feel like I am starting to get the basics down, and that will set me up to know my shit better down the road. I just finished learning all the basic Hiragana, and now I will be finishing up the combination Hiragana and Dakuten before moving on to Katakana! I know this will be a slow moving process, but I’ve got nothing but time.

オンワード!

Gin Template Functions
>>

Good news! Also, annoying news! The day I finally finished and uploaded that last post about rendering Markdown in my Go microblogging engine, Gin (the http framework I am using) was updated to v1.2, which included 🎉 Template Func Maps. 🎉

This is great news because I got to rip out the hacky workaround I talked about in my last post. And this is annoying because if I had procrastinated on that feature as long as I procrastinated on finishing that blog post, I would have saved myself some time.

But, no use dwelling on the past and what could have been. Thankfully, not much had to change in my code to work with Gin’s template function loading.

router.SetFuncMap(getFuncMap())

That looks way better than the html/tempalte implementation. I like the idea of keeping my server.go file as clean and simple as possible, so I am very glad that this added.

Storing and Rendering Markdown with Go
>>

Update: Literally the day I finally got around to finishing and posting this, Gin, the framework I mention using, added support for custom template functions. That makes almost everything in this post obsolete. But I am going to leave it up for posterity and so everyone can laugh at me. I posted an update here

Currently, I am working on writing my own little custom microblogging engine. Inspired by my friend’s microblog that he wrote in Python, I wanted someplace to post smaller updates as I work on various projects. There is a fair amount of overhead in posting to this blog. For one I need to be on my personal laptop because I am too paranoid to put anything personal on my work laptop, and I have to build and deploy this site every time I want to post something. This isn’t normally an issue because of the time investment in writing a blog post. I normally spend one to three hours writing a blog post anyway, so the extra couple of minutes to build and deploy are really nothing. This wouldn’t really work with a microblog though. When I only spend thirty seconds writing a small update, then building and deploying becomes the bottleneck. I wanted to be able to post quickly from the command line. I also wanted to take the opportunity to write a small app in Go because I learn best when I have real problems to solve.

I will have to write more about this process, because Go is amazing and fast and I really have enjoyed this project, but right now I wanted to focus on one particular aspect, storing and rendering Markdown.

Naturally, I wanted to write my microblog posts in Markdown, and when I’ve written web apps in Rails, markdown rendering was pretty easy: the Redcarpet gem took care of all the heavy lifting. But I had no idea if there were even any Markdown parsing libraries on Go at all.

Luckily, I found Blackfriday which did exactly what I wanted, parsed Markdown into HTML before being saved to the database. When I previously used redcarpet, I would store the markdown in the database and then parse it when it was being rendered on the page, but doing the parsing first is probably faster and safer. The Blackfriday documentation recommended using another library called Bluemonday to sanitize the HTML before saving it for an extra layer of safety. I am really the only one who is going to be using this, so it probably wasn’t super high risk, but it was just another line of code so why not.

No that I had Bluemonday and Blackfriday parsing my Markdown and storing it in the database as html, I needed a way to render the escaped html on the page when listing out posts. There wasn’t a super obvious way to do this. I found some possible Go functions that could be used to escape HTML in templates (raw and unescape) but they seemed to be deprecated. I eventually found the template.HTML function in the template/html library that would do what I wanted, but I still couldn’t use it in a view.

I Googled around a bit and found that you can define custom template function by passing a template.FuncMap when you load in the template. You can find the definition of FuncMap here but basically, it was a map of names and functions that when passed to the template loader, will open up those functions to be used in the template. Great, except that I am using the Gin framework instead of the standard library http functions, and Gin doesn’t support loading in custom functions.

After a little more Googling, I found that a few other people were having a similar problem. The solution was to use the template loader from template/html and then Gin’s support for custom template renderer. Then I can pass in a function to the template renderer that returns a FuncMap with my function to use tempalte.HTML to parse the stored html from the database. Then I could finally use that function in my html template file to render the html from the post. All in all, the process looks like this.

markdown -> Blackfriday -> Bluemonday -> Database -> FuncMap -> template.HTML -> Template

Its a little complicated. Anyway, here is the actual code implementation for this. Its probably more helpful than that diagram.

// use default gin router
router := gin.Default()

// use html/template to load in template files
// See also https://github.com/gin-gonic/gin/issues/228#issuecomment-105228770
// .Funcs() is the function to pass your FuncMap
// here i passed it another function that retured that FuncMap.

tmpl, err := template.New("views").Funcs(getFuncMap()).ParseGlob("templates/*/*.html")
if err == nil {
// Send the templates to the Gin router 
	router.SetHTMLTemplate(tmpl)
} else {
	panic(err)
}

And here is the helper function to define the FuncMap

// see also https://github.com/gin-gonic/gin/issues/228#issuecomment-76547401
func getFuncMap() template.FuncMap {
	return template.FuncMap{
		"html": func(s string) template.HTML {
			return template.HTML(s)
		},
	}
}

The key part here is what is inside the return template.FuncMap bit. The key in this map is html and the value is a function that takes in a string, and returns an instance of template.HTML, which is escaped when rendered on a page.

In action, I just add {{ html .Body }} to my template file, and bam, rendered html that was originally input as Markdown. It was kind of roundabout but not too bad in the end. Just a lot of functions within functions within functions.

Tumblr Deserved Better
>>

Its official. Verizon now owns Yahoo, but this isn’t a post about Yahoo. For all I care, Yahoo can rot in the dumpster that is Verizon’s digital strategy with AOL. But caught up in all this is Tumblr. I have a hard time putting my sadness about Tumblr into words, but I am going to try. All I ask is some patience. This is a rare showing of sentimentality for me.

It’s easy to make fun of Tumblr, the same way that adults find it easy to make fun of anything that is popular among teenagers. But Tumblr has gotten an especially bad reputation around the tech community. It seemed to fall out of “relevance” fairly quickly. There was a time when people tried out Tumblr for semi-serious blogging or writing, but now it has the reputation of being mostly teenagers with bad senses of social justice and unhealthy obsessions with British television shows. Oh, also porn.

True or not (I’d argue not, or at least oversimplified), Tumblr deserved better. Founded in 2007 by David Karp and CTO Marco Arment, bought by Yahoo in 2013, now sold off to Verizon. Mismanaged all the way. This narrative, which mostly centers around Tumblr’s viability as a startup and product. But this misses how important Tumblr was to the people who used it.

How many anonymous forums do teenagers get? Where they can be really themselves around people who are like them? With no fear of being outed or found out? Not a lot. And that is what Tumblr was to many kids. How many queer kids felt lonely until they joined Tumblr and found both people like them and the words to describe themselves? I would bet it was a large number. And now those kids might lose what could be their only safe space because of Silicon Valley politics. All Tumblr kids wanted to do was be themselves and ship fictional characters.

For me, it was a place to be unapologetically nerdy in a culture and a hometown that discouraged intellectualism and geekery. It was how I got to know all of my closest and best friends. I moved halfway across the country on my own. It was reassuring and comforting to share gifs with people I had just met and know we were cut from the same cloth. I’ll always treasure that time in my life. I met a long term partner through Tumblr. Now that I think about it, all of my major relationships started, at least in part, on or around Tumblr. More recently, its been a place I could experiment with my identity expression without fear.

Recently, bookmarking site Pinboard acquired bookmarking site Delicious mostly because Delicious was passed around by corporations (including Yahoo at one point) and was mismanaged into a pale imitation of its former self (sound familiar?), and Pinboard wanted to preserve Delicious as a piece of Web history. I don’t think anyone will extend that kindness to Tumblr. If I was rich; however, I would buy it without hesitation, and make sure the servers stayed up for a long time.

WWDC 2017
>>

TLDR: The tech was mostly great. Everything else, not so much.

I went into this WWDC 2017 keynote not sure where I stood on Apple and their products. I had already decided that my next computer will be a desktop gaming PC and I was fairly sure that my next laptop would be a cheap PC running Linux. I had even considered going Android for my next phone. Before this, I was almost certain.

Now, not so much.

The Presentation

I got this idea from Aleen Sims, but I kept a count of the diversity statistics on stage at the WWDC keynote. Of the people on stage with speaking roles, there were 10 white men, 2 white women, 1 woman of color (who was also pregnant). The last couple of Apple Keynotes seemed to be moving in generally the right direction with their diversity statistics. The Apple Music presentation featuring Bozoma Saint John was a particular highlight. But this year was a step back. In 2017, being the biggest company in the world and having double digit white guys on stage is unacceptable.

The few women who were on stage all did fantastic. One women from Epic Games was demoing VR Development on a Mac using the HTC Vive, and she performed a 1) live demo while 2) wearing a VR headset with 3) no script or teleprompter that required 4) to physically move around a set. That was seriously impressive. One of the presenters was also very pregnant. I don’t ever want to have children for a reason, I can’t imagine that was easy, but it was a great image that pregnant women are just as capable as anyone else. I just hope Apple treats its pregnant employees with respect behind the scenes.

Sigh. Okay, it seems that every Apple keynote these days has one part or another that is controversial. Last yeah it was Phil Schiller describing Apple removing the headphone jack on the iPhone 7 as “Courageous”. For me, that moment this year was a transphobic joke made by the (generally genuinely funny) Craig Federighi. While talking about iOS 11’s new Drag and Drop feature, Craig said, “Its a drag fest.” Cue laughter. I can’t tell if this was scripted or just something he ad libbed, but I don’t know which would be worse. I don’t think I need to explain why this hurt me as much as it did. I saw a couple other trans people on twitter describe it as having all your enthusiasm run headfirst into a brick wall. Can confirm, that was pretty much the feeling. Infuriatingly, this blatantly offensive “joke” will get none of the Apple press outrage that the courage line did. I wonder why.

This leads me to my final thought on the actual presentation. I am so tired of white, straight, middle aged dude sensibilities in tech. Dad jokes. Stupid video skits. etc. Its all so boring and dull and I am sick of it. Its also how a transphobic joke can go basically unnoticed in the community. Its so exhausting.

Mac Software

  • Mail / Photos: Not much here. ¯\_(ツ)_/¯
  • Safari: The privacy features for stopping autoplay video and fighting cross site tracking are fantastic. I use Chrome and some plugins to do the same thing, but making it the default for Safari will bring at least some level of protection to a much larger audience. Always a win. Also, I’ve heard that Safari when its updated will support WebAssembly, very nice.
  • Metal 2: I am a little disappointed that Apple is showing that they wont support Vulcan or other graphics standards that literally everyone else is using, but if they can get engine makers and developers on board (neither easy nor guaranteed) then it will come out in the wash anyway. I was also genuinely surprised there was so much emphasis on VR. I am skeptical of both VR in general and VR on the Mac, but time will tell.
  • APFS: ding.

Mac Hardware

  • iMac Pro: Wow. I know most of the impressiveness of this product is the large numbers that don’t really mean too much, but those large numbers are pretty damn impressive. And I am a sucker for Space Grey anything. I only wish I had a job that justified needing to use it.
  • MacBook updates: 👍
  • External GPUs: 👍
  • AMD GPUs: 👎
  • I want all the computers.

iOS

  • AR Kit: Cool. I’ve got some ideas on things I could do with this.
  • Too Much Machine Learning: Seriously, cool it with the buzzwords.
  • Nice for people who use iPads (not me)
  • I am not a fan of the new design language.

Miscellaneous

  • Pride Watch Band! I know corporate expressions of queer pride are problematic, but I really want a pride flag watch band.
  • Homepod: bad name. Not working with Spotify is a deal breaker
  • I wonder how much of this will work reliably
  • That is now how you pronounce Reykjavik, Craig
  • I had no interest in anything in the watchOS section. I don’t need useless watch faces and notifications to guilt me into working out more.

Wordpress
>>

This is probably not an original thought but Wordpress is awful.

I think its a relatively well-designed CMS that is really good at letting people make websites without too much thought or programming knowledge. But I have a number of major problems with Wordpress.

Security

The plugin and theme engine in WP allows for any arbitrary third-party code to be executed on your website (potentially on your server/PC). This is a giant, glaring hole in the security model, that Automattic has kind of taken steps to counteract. For example, using Wordpress.org’s hosting features for your site 1) is more secure and 2) you don’t have to manage your own server but then your site and content are trapped and held hostage by Wordpress.

Storing Configuration in the Database

Most websites and web apps these days are two things, a bunch of files (code. and a database. This generally makes collaboration between developers easy because the code files can be checked into a version control system like git and Github, and easy shared. The database is more complicated.

Take a Ruby on Rails application, for example. Two developers are working together and all the code is checked into Github. The way RoR is architected ensures that the data in the database is arbitrary and volatile. It doesn’t matter what is in the database, really. As long as the schema is consistent, it doesn’t matter if a user has one email or another. Rails solves this by including scripts and functions to take a saved state of the structure of a database and recreating it. Then there are seed files that can load data.

Wordpress is different. Wordpress stores site-wide settings in the database. Flip an option in the settings view or update a page, and that information is stored in the database. So two developers can’t just collaborate on a WP site together because the configuration changes are saved to the database. So you can’t just pass the schema back and forth between developers because you would be missing crucial configuration changes. Infuriating.

Single Table content structure

All of the actual content on a site are stored in one database table. This is idiotic to anyone who has taken a 101 course on database design.

Other People

The people who developer Wordpress themes and plugins are committed to twisting and changing Wordpress to do whatever they want it to with a disregard for what WP is inherently weak or strong. This leads to tedious and unmaintainable Frankenstein monsters of websites.

This was mostly prompted by having to work on way too many Wordpress sites at my day job. </rant>

SCOTT HANSELMAN: Ruby on Rails on Azure App Service (Web Sites) with Linux (and Ubuntu on Windows 10)
>>

This is a great post from Scott. I’ve only recently become familiar with his writing and excellent podcast Hanselminutes but he does great work.

The Linux subsystem for Windows was the start of my process of actually looking at Windows as a suitable operating system to do software development on, and if getting a Rails environment set up on windows is as easy as Scott makes it look, then I am sold.

I am not particularly attached to any of the OS level features of macOS, especially since rediscovering how good VS Code is. My recent push towards moving all my data to cloud services has made me more platform agnostic than ever (why hello Samsung Galaxy S8), but what I would really miss if I moved to Windows is the command line. Unix, and by extension Linux I guess, makes it so easy to do software development, that I was considering a dual setup of Windows for gaming and then a flavor of Linux for development.

Anyway, that is all probably best saved for another post. My point is, if you are a web developer who is annoyed at the slow progression of the Mac operating system and hardware, take a look at Scott’s post.

Is the iPad a Professional Machine?
>>

This is sort of a follow up to a post I wrote last month. I had this thought at like five in the morning as my cat was waking me up for breakfast. There has been a lot of strife in the Apple tech community about iPads and Macs and what “professional work” is and what the future of computing looks like. My opinion on this probably means very little. I’ve been an Apple fan for years, but I’ve been a planning on moving to Windows/Linux and Android recently. So take all this with a grain of salt.

As I mentioned in my “OS is the new Linux” post, there are plenty of people who run their professional lives on an iOS machine, mainly the iPad Pro. However, just because Apple markets the iPad as a “Pro” machine, and just because some people can do their professional work on an iPad, doesn’t mean that iPads are Professional computers, or even general purpose computers. For example, you cannot write and publish iOS apps (or web apps for that matter) on iOS. You must own a Mac if you want to make apps for Apple’s platforms. So by design, there are things a Mac can do that are not only difficult, but impossible on an iPad.

Is Apple motivated to change this? I don’t think so.

Lets ignore the fact the right now, there are hundreds of engineers within Apple that need tools to do their job that will probably never be available on iOS. I doubt the team designing Swift would be able to do their job without a command line. For the sake of argument, lets ignore internal Apple needs.

Say the magically overnight, you could do software development on an iPad, how many programmers would switch to using an iPad? Some probably would, especially if iPads are the future of computing. Say that iPads become truly a general purpose computer and that Apple stops making Macs altogether, that means that they just lost the product line with the highest average selling price by far. Maybe, maybe, Steve Jobs would have done this, cannibalized Apple’s highest ASP product for the sake of progress, but Tim Cook absolutely will not. Maybe I am putting too much stock in how much Apple cares about ASP, but even leaving that behind, Tim Cook has shown that he is willing to keep products around just because someone will buy them, hell look at the Mac Pro.

If you remove every other factor that differentiates iPads and Macs, and just look at iOS app development, it seems reasonable to me that Apple would want to keep app development as something that you can only do on the Mac if for no other reason than to continue to require developers to buy an extremely expensive Apple product. Maybe its in Apple’s best interest to keep the iPad a consumption only device.

Oh Bootstrap, I'll Never Leave You Again
>>

Oh Bootstrap, I’ll Never Leave You Again

I am not a designer. I don’t like designing front-ends for websites. It’s tedious and I am not good at it so I mostly just spend hours moving CSS values up and down in Chrome Dev Tools until it looks right to me. Oh wait, I have to also got through the same process again for each responsive breakpoint. No thanks.

Which is ironic, because I started at my job-y job as a front-end intern. But it’s not for me. I can write SQL queries happily all day, but please don’t ask me to touch your CSS. It will look bad and we will both be unhappy.

All this is to say that this is why I stick with front-end frameworks, because the less I have to design, the better. My framework of choice is Bootstrap. Its quick to get setup, has some sensible defaults, and looks pretty good. Unfortunately, the popularity of Bootstrap has contributed to the “Every Website Looks the Same” syndrome that the Internet has been experiencing over the last several years. Because of that, and because I wanted to really simplify my reliance on dependencies, I’ve tried to move away from Bootstrap where I can.

With my this site, that meant no front-end framework at all. I stole some CSS from a couple of other blogs I enjoy reading and tweaked it to fit what I was going for, which was simple and fairly information dense. The result of this was this site being unusable on a mobile device (see also: I am not a designer).

For my next big project, What Do They Look Like?, I wanted to try out Thoughtbot’s Suspenders gem to generate the template for the Rails app. This turned out to be a great idea in the short term, and terrible in the long term for a couple of reasons (one of which is trying to self-host a web app that is specifically configured for Heroku), one of which was that Suspenders generates your app bundled with the Bourbon front-end framework. I thought this would be fine. I wanted to try bout Bourbon anyway as a possible framework for sadrobot.software.

The problem was that, unlike Bootstrap which pre-defines all the styling for you into HTML classes, Bourbon was a mix-on library for CSS and SCSS. I thought I would be able to load Bourbon, and just add some classes and ids to my HTML and be golden, but I had to both define the SCSS styling and structure the HTML. So I pulled some example CSS from the Bourbon website and got the bare bones working. It looked good.

The main feature of What Do They Look Like is that the directory is basically just a grid of faces or images with a name below it; easy to navigate, search or just look at. Trying to get a grid of faces and names working in Bourbon without spacing issues was…a problem. If an image was too large or a name was too long, there would be clipping. That was not okay for me. Forcing my images to be square was no problem, but I could not compromise on people’s names being cut off, so I got frustrated and ripped the Bourbon grid out and replaced it with Bootstrap.

I hate feeling like I am hacking and breaking CSS, I hate feeling like I am using !important too much. I can write well-designed Ruby code, but I find it impossible to write well designed CSS. With yarn and a little bit of fussing with import statements, I had my grid working again. It was responsive with big images and clear text. And it didn’t clip anyone’s name off. And I didn’t have to hack CSS to do it.

I love you Bootstrap. I will never wander again.

Deploying Rails to a Linux VPS
>>

This is part three in my series on hosting a Rails application on a Linux Virtual Private Server. You can read part one here and part two here.

It’s About Time

Finally we are going to talk about what you actually do once you have a fancy new Linux server up and running. We are going to put our website on the Internet!

The stack that I use is Nginx with a Puma proxy for the web server, Postgres for the database, and rbenv to manage the Ruby version both on my local machine and on the server (RVM people, don’t email me). Finally we are going to configure out Rails app to use Capistrano for deployment.

Installing your Web Server

Every guide I’ve ever read has the first step of doing anything as updating your package manager so in that great tradition:

% sudo apt update && sudo apt upgrade

First things first, we will need to install Nginx and some other dependencies for later. You might have already installed git, but if not, make sure you do now.

% sudo apt install curl git-core nginx -y

Installing Your Database

Next we are going to install Postgres (I refuse to call it PostgreSQL). We also need a user that our application is going to use to connect to the database when it runs. Conventionally, that user has the same name as the application. I like to create my database at this point too, just because I am going to be in the psql interface and I would probably forget if I didn’t get it over with.

% sudo apt-get install postgresql make postgresql-contrib libpq-dev -y

Along with Postgres, we are installing make, the GNU collector of executables, and libpq, which is the C library for interfacing with Postgres (you will not have to worry about this).

Like I said before, we also need to create a user (or role) in the postgres database for our application. This command is a little hairy.

% sudo -u postgres createuser -s user_name

sudo -u postgres means “run the following command as the postgres user.” postgres is the default superuser account for the database and so we want to use that user to run commands against the database until we have our own application user. Replace user_name with the name of your application, or whatever user name you want to use to connect your app to your database.

This is all boring database admin, but hang in there, we will get to the fun stuff in a second. Next, we have to log in to the database interface to set the password for our newly created database user.

Much like our previous command, we need to use the postgres user to access the psql interface to the PostgreSQL database (confusing).

% sudo -u postgres psql

You will never guess what the command for resetting a user’s password is.

posgres=# \password user_name

Pick a strong password, and make sure you store it somewhere secure like a password manager because you will need to at least one more time.

While you are logged in, create your production database. The convention here is appname_environment.

postgres=# CREATE DATABASE appname_production;

Then you can exit psql. This is not super obvious at first because while most command line interfaces use some form of exit to quit, psql uses

postgres=# \q

Yay databases! If you have an existing database the you would have dumped and would like to load the data from, you can run this command:

% pg_restore --verbose --clean --no-acl --no-owner -h localhost -U myuser -d mydb latest.dump

But if you are setting up an app from scratch or deploying for the first time, no need to worry about that just yet.

Installing Ruby <3

Finally! The relatively fun stuff. Before we can get our application up on the server, we need the Ruby programming language, and a way to manage what version of ruby is installed. If you are using a environment manager for Ruby on your development machine (which you should be) you can just use that one for your server. Like I said before, I use rbenv so if you use RVM, the following commands will be different and you will have to sub out rbenv for RVM in future commands or configuration.

There are some more packages that need to be installed first. I wont go over what each of them does, but they are all needed down the line.

 %  sudo apt-get install make build-essential nodejs libssl-dev zlib1g-dev libreadline-dev libyaml-dev -y

Luckily for us, there is a rbenv installation script we can run to get up and running fairly quickly.

% curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash

That will probably end by giving you a message about how you need to put rbenv in your path variable. Down the line, its also going to ask you to add some more settings into your path. To save time, just add them all now. Run the following commands to add the Path config to the rc file for whichever shell you are using (the default is bash so use .bashrc, but I use zsh).

% echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
% rbenv init
% echo 'eval "$(rbenv init -)"' >> ~/.zshrc
% source .zshrc

Along with that installer script for rbenv, there is also a rbenv doctor script that just runs the checks to make sure that everything is setup correctly. We can run this with

% curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash

If there is anything missing, that script will tell you the command you need to run. It will say there are no versions of ruby installed, so lets take care of that.

 % rbenv install 2.3.1
 % rbenv rehash
 % rbenv global 2.3.1
 % ruby -v

The first command will install Ruby version 2.3.1 (replace this with whichever version is most recent) and then next two will tell rbenv to use the version of Ruby you just installed as the global Ruby version. If all goes according to plan, the output from ruby -v should be 2.3.1.

Install Rails and Bundler

Rails and bundler are the two gems you will need to get a basic app up and running, so you want to install them now.

% gem install rails -V --no-ri --no-rdoc
% gem install bundler -V --no-ri --no-rdoc

The -V flag is verbose output, --no-ri and --no-rdoc prevent any documentation from being downloaded so that the gem takes up as little space on disk as possible.

Okay! I think that is everything for getting the server prepped for our Rails application. Next we are going to go through the configuration steps for getting a Rails app deployed using Capistrano.