Is that even possible? OK, I admit it’s not. But don’t leave yet! Let me explain.
What I’m talking about is Rails application development isolated away from your development machine. So while you technically still need Ruby and Rails somewhere, you don’t need them cluttering up your local machine.
I’ve been developing Ruby on Rails for almost 10 years now (that makes me feel really old). While Rails is a really amazing framework, and Ruby a very beautiful language, there have always been a few things about Ruby on Rails development that have bothered me.
How do you manage versions of Ruby between projects? You create a version manager so you don’t have to.
RVM
or rbenv
, that is the question…
Version managers give you everything you need to download, install, list, and switch versions of Ruby, but honestly, it’s a pain (not as much of a pain as before, but still a pain).
I can’t remember how many times I’ve install a new gem and forgot to rbenv rehash
to get the shim loaded into the environment, so I’m sitting there scratching my head as to why it’s not working...
It’s so tedious managing versions of Ruby, versions of version managers, and making sure I’m running the same version of everything that the rest of my team is… ugh.
Things don’t get much better here. The gemfile
is a straight forward way to declare dependencies, and bundler
makes it easy to get/update them all. But that’s about where it ends.
And where do all those gems I install go anyway?
They all get stuffed into a folder, under the current version of Ruby, sitting on your local machine. Hundreds and hundreds of files. That’s crazy right? Throw in node_modules
and bower_components
and you’re probably talking about millions of lines of code you’re storing for each project you work on!
This is everything that’s left over from the previous two. I don’t know about you, but I don’t usually think to go clean all that stuff up once I’m done with a project.
I dare you to check how many versions of Ruby you have installed… If you’re using rvm
it’s rvm list
, with rbenv
it’s rbenv versions
.
You’re probably lucky if you six or less. Most likely you have closer to 12 (I won’t even ask you to check how many different versions of all the different gems you have installed across each version of Ruby for each project you’ve ever worked on).
Is it just me or does it seem like there should be a better way…
Taking a step back for a moment, Ruby and Rails development compared to most other workflows is still really great. But it’s 2017 now. I think it’s finally time that all of that ^, was straightened out.
The way to do this is with isolated development environments. Rather than having everything on your work machine, it could be tucked away in its own environment created specifically to match an application’s needs.
This would eliminate the need for version and dependency managers, eliminate version and dependency conflicts, and would free up space and clean up file systems.
One way of creating isolated dev environments is with Vagrant and VirtualBox. This method is a little dated, but still somewhat effective.
The new kid on the block is Docker.
Docker makes it easy to create these isolated environments using containers. While Docker is really cool, and represents a giant leap forward in containerizing applications, it gets complicated very quickly.
Once your application grows and you have dozens of containers running multiple microservices and you have to get things like Kubernetes or Swarm in the mix… it’s a mess.
When you have to start adding things that help manage things created by other things that are all intended to make things easier… it’s always gets more complicated.
The best way is to just forget all that stuff. Just forget it.
As an application developer, I don’t want to worry about setting up my development environment just right. I don’t want to worry about maintaining parity between that environment and whatever the production environment is going to look like, and I certainly don’t want to even think about creating, configuring, or managing, a production infrastructure…
The way to eliminate all this is by using a micro-PaaS. The whole concept of micro-PaaS is that your applications environment should live with your application.
A micro-PaaS uses a simple config file at the root of a project to define that applications environment. Since this config file lives within the application, wherever your app goes, your environment goes with it.
Think about the implications here…
You create your application, easily share it with your entire team, and guarantee that everyone is running on the exact same infrastructure. You don’t need to worry about that one person who can’t ever seem to get the application running, or the new guy who will take up days of your time getting them set up and productive.
The other huge benefit of a micro-PaaS is that, again, since your application’s environment lives with the application code, you don’t have to worry about creating or configuring a production infrastructure. You just deploy your code and the infrastructure is created and configured for you.
This guarantees exact parity between all environments; development, staging, production, whatever.
If you can relate to anything I’ve talked about here and are ready to improve your development workflow, Nanobox is a micro-PaaS that you can start using right now.
Nanobox gives you all the power and flexibility of containers by leveraging Docker to create virtual development environments. This keeps your projects isolated and your work machine squeaky clean. You don’t have to worry about the details of getting you application’s environments configured, it’s all handled for you.
If you’re like me, and want to avoid at all costs the complexities of infrastructure configuration and management, without the limitations of a traditional PaaS, Nanobox makes it easy to deploy your application to any provider. You can easily deploy to AWS, DigitalOcean, Linode, or even a custom provider you define. No more vendor lock-in, yay!
With a simple boxfile.yml
at the root of your project, you define a local dev environment:
run.config:engine: ruby
extra_packages:- nodejs
With a few modifications to the same config file, you define an entire production environment:
run.config:engine: ruby
extra_packages:- nodejs- nginx
deploy.config:extra_steps:- rake assets:precompile
before_live:web.main:- rake db:setup_or_migrate
data.db:image: nanobox/postgresql
web.main:start:nginx: nginx -c /app/config/nginx.confpuma: bundle exec puma -C /app/config/puma.rb
writable_dirs:- tmp- log
log_watch:rails: 'log/production.log'
worker.main:start: sidekiq
Stop wasting your time and energy with version managers, dependency managers, environment setup, and infrastructure configuration and management.
Spend time doing what you really love doing… developing your awesome application!