Engineer's Guide To Windows: Ruby on Rails
As I've mentioned, I primarily work with Ruby on Rails applications. So it's fairly important that I can work with one on my sweet new WSL setup.
Mixed Bag of Prerequisites
Unlike a more standard Debian or a fresh macOS install, a clean WSL Debian install has a very minimal set of tools installed. So before getting into anything strictly Ruby or Rails related, I need to install some common tools I end up reaching for to accomplish all sorts of work, including getting a Rails dev environment setup.
sudo apt install ssh git man-db curl gnupg2 wget keychain
Nothing here should be too controversial to anyone who has worked in Unix-like systems before.
I was a little surprised that I needed to install the
man database, but sure 🤷♂️. Installing
wget are reasonable basics to have on a Linux system and are required to install Ruby and Node through version managers. I use
gnupg2 to sign my commits to get that sweet verified badge in GitHub.
keychain is new for me. It's a handy tool to manage your ssh and GPG keys. Once installed, add
eval `keychain --eval --agents ssh id_rsa` to
.bash_profile, then enjoy not having to type a passphrase every time you run a GPG or ssh command!
The Journey to Install Ruby
It's possible to grab Ruby (or Node, for that matter) versions from the Debian package manager, but I don't believe that's the most common or recommended way to install them. I always end up needing multiple or unavailable versions for one reason or another, so I lean on rbenv to manage installing and switching between those versions.
Use rbenv to pick a Ruby version for your application and guarantee that your development environment matches production. Put rbenv to work with Bundler for painless Ruby upgrades and bulletproof deployments.
I chose to install rbenv with the rbenv-installer script (after reading the source over).
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash
Now rbenv and ruby-build should be installed; just don't forget to run
rbenv init and follow the instructions to have the shell recognize and find Ruby binaries.
Theoretically, any version of Ruby should be installable at this point!
$ rbenv install 2.7.2 Downloading ruby-2.7.2.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.bz2 Installing ruby-2.7.2... BUILD FAILED (Debian 10 using ruby-build 20201225-2-g5de6d5f) Inspect or clean up the working tree at /tmp/ruby-build.20201230170140.1599.9kPeZh Results logged to /tmp/ruby-build.20201230170140.1599.log Last 10 log lines: checking for ruby... false checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... no checking for cc... no checking for cl.exe... no configure: error: in `/tmp/ruby-build.20201230170140.1599.9kPeZh/ruby-2.7.2': configure: error: no acceptable C compiler found in $PATH See `config.log' for more details
Well, that's not good 🙈.
After seeing that error message, I hoped that installing GCC would be enough, but of course, there were a bunch of libraries missing too! I'll spare writing out the half dozen tries it took me to get all of the necessary libraries installed and get to the point.
sudo apt install gcc libc-dev make libssl-dev zlib1g-dev libreadline-dev
Those are what's needed just for Ruby. For my Rails app, I also needed to install
libpq-dev to compile the Postgres gem, and
g++ for the sassc gem.
Like with Ruby, it's good to have a version manager for all your Node needs. My preferred version manager for Node is nodenv, which, nicely enough, is the Node version of rbenv. 😎
It even has a similar installation process.
curl -fsSL https://raw.githubusercontent.com/nodenv/nodenv-installer/master/bin/nodenv-installer | bash
Again, just like with rbenv, follow the post-install instructions to ensure the shell recognizes and finds the binaries. Hopefully, as for me, installing Node will be much less eventful than Ruby was.
There is no reasonable way I know to cover the possible variations of Rails setups here. For clarity and sanity's sake, I'll limit this guide to generating a brand new app. Even more narrowly, this is the command I want to work:
rails new mycoolapp --skip-turbolinks --skip-action-cable --webpack=stimulus --database=postgresql
As long as Node was successfully installed, installing Yarn is a one-liner.
npm install --global yarn
Keep in mind that Yarn will be installed in the current Node version, so verify it's the expected one with
Postgres is my go-to database for any project. As of this writing, the primary version available in Apt is Postgres 11, but pulling from the Debian testing source will get Postgres 13 for bleeding-edge database fun. Thankfully, installing is straightforward. As I mentioned earlier, make sure
libpq-dev has been installed at some point, so the pg gem will be able to compile.
sudo apt install postgresql libpq-dev
It will not likely be a revelation to those who have experience with later versions of Postgres or who have only worked with it through Homebrew on a Mac, but I ran into some additional steps I needed to run through to connect to the database. After Postgres installed, I didn't have a way to create users, databases, or even access it with psql. It turns out I had to bootstrap myself a user through the
postgresql) system user.
sudo -u postgres createuser --createdb --pwprompt WHATEVERUSERNAMEYOUWANT
I prefer to always create a Postgres role that matches my Linux username since that's the default if you don't specify a role name when using
There is another way to work with databases locally, though it might be a little iffy on security. If this is strictly for development purposes, I don't think it's much of an issue. When creating users, leave off
--pwprompt and change the Postgres config to instead trust any local connections. This can be done by updating
/etc/postgresql/11/main/pg_hba.conf to have
trust for authentication.
# "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust
After the configuration change, any user or app's local connections will connect with only a username, no password required.
What would working in Ruby be without Bundler? As long as Ruby is installed, this is as easy as
gem install bundler
Rails Itself 🤔
For completeness sake, installing the Rails gem should be the last piece of the puzzle to run that command I mentioned at the start of this section. Grab it just like Bundler
gem install rails
Enjoy Building A New Application
A compact version of the output, but now generating a new Rails application should succeed! Maybe take a break, grab some water and a snack, then get to work on building a great side project.