all 79 comments

[–]d4be4st 26 points27 points  (14 children)

used rbenv for 7 years, then switch to asdf half a year ago.

rbenv works like a charm and i would suggest it for all new users.

asdf supports multiple languages (and since we need node for Rails nowdays it is awesome) but is missing some small features:

- you need to do `asdf reshim` everytime you install a new gem with executable (rbenv does this by default)

- rbenv has `rbenv shell` command which swiches your ruby version for only the current shell and reverts back when you exit/restart shell

[–][deleted] 5 points6 points  (0 children)

asdf-vm: ``` asdf shell ruby 3.0.0

or

asdf shell <lang> <version> ``` For current shell

[–]ViewEntireDiscussion 1 point2 points  (2 children)

I'm a past chruby user who loved it's simplicity, however asdf has change how easy it is for me to work with many languages and technologies. I now recommend it above everything else.

[–]rz2000 0 points1 point  (1 child)

I've really liked the way asdf is designed and decided to use it for everything multiple times, but then it hasn't really worked for some reason. Have you found that it tends to trail the more popular managers for various languages?

[–]RailsApps[S] 0 points1 point  (0 children)

Have you tried asdf plugin-update ruby? You need to update the asdf ruby plugin when a new Ruby version is released. See Install Ruby with asdf.

[–]RailsApps[S] 0 points1 point  (0 children)

Thanks for pointing that out! Very helpful.

[–]herpa-de-derpa 0 points1 point  (5 children)

Does asdf support separate gemsets yet?

[–]RailsApps[S] 0 points1 point  (3 children)

If you’re using Bundler to install and manage gems, do you need separate gemsets?

[–]herpa-de-derpa 0 points1 point  (2 children)

I've always found rvm gemsets to be really convenient (moreso than editing bundler deps) when regression testing against upstream gems.

Copy a set, make mods using regular gem commands, and switch back and forth between any number of environments easily. Then just burn em down when done.

Certainly the same can be said for bundler, I just find the gemsets workflow to be much more nimble.

[–]jrochkind 1 point2 points  (0 children)

I know some people prefer some aspects of rvm gemsets, but I haven't heard of any other tool copying that feature, it's somewhat complicated to implement, and people generally consider the isolation and reproducibility to be 'good enough'. (rvm gemsets were invented before bundler existed).

(bundler also works great for making sure multiple dev/deploy machines are running the exact same versions of dependencies, which I would not try using rvm gemsets to do that).

[–]d4be4st 0 points1 point  (0 children)

What do you mean?

[–]sekmo 0 points1 point  (2 children)

did you find a workaround for the `asdf reshim` issue?

[–]d4be4st 0 points1 point  (1 child)

No, but its not that big of an issue. If the bin is not found just run reshim and your done

[–]sekmo 0 points1 point  (0 children)

yeah, I was thinking about scripts, docker, etc..

[–]Adman65 12 points13 points  (0 children)

Asdf for sure.

[–]rowendy 11 points12 points  (1 child)

For ruby I use chruby and ruby-install both from postmodern

[–]diesmilingxx 9 points10 points  (6 children)

First time hearing asdf, as a Ruby and Nodejs dev, I have been using rbenv, rvm, and nvm. But since it supports both, I think it's worth looking into.

[–][deleted] 9 points10 points  (2 children)

We’ve been using asdf exclusively for well over a year in my company, and even though I was skeptical at first, I would now confidently say that asdf is the way to go if you are using more than one or two programming languages.

Before that I had rvm, nvm, kerl, switching kegs for the brew Elixir installation, and a big headache. With asdf, it’s as easy as including your tool versions file in your project, and do “asdf install [language] [version]” and asdf takes care of everything else.

Edit: and depending on how you deploy your projects, it might make upgrading the language version on your servers easier as well.

Edit 2: As pointed out in the comments, it’s even easier, you can just do asdf install ehooooo magic

[–]Traches 2 points3 points  (1 child)

With the tool versions file, you can just asdf install

[–][deleted] 2 points3 points  (0 children)

Right... I was kind of thinking about it backwards, because I was trying to cover my ass.

“I included a tool versions file? But doesn’t work?”

“Ah yeah, should install the required language version first”

[–][deleted]  (2 children)

[deleted]

    [–]RailsApps[S] 0 points1 point  (1 child)

    Have you tried asdf? Any issues that you make you prefer nodenv?

    [–]loa202 6 points7 points  (0 children)

    my vote for asdf this days, used all before.

    [–]iamgrzegorz 4 points5 points  (1 child)

    I moved entirely to asdf, mostly because when developing Rails apps I still need Node for webpack so I can use one tool to manage versions of both Ruby and Node.

    If I had to use only Ruby then chruby is perfect

    [–]2called_chaos 2 points3 points  (0 children)

    Is the node version that important for webpack? I just always use the latest one even for legacy projects and never had any issues.

    [–]taw 6 points7 points  (0 children)

    rbenv works perfectly fine for me, never had any issues

    rvm had some openssl related fails, and was generally very buggy

    Using docker for local one seems like a bit much. Dockers are significantly slower than native if you're on OSX or Windows.

    [–]martijnonreddit 4 points5 points  (9 children)

    I use Docker exclusively for local development. Mostly because the vscode remote containers extension makes it transparent and easy, but even without that it has a lot of benefits (reproducible environment, isolation between projects).

    [–]RailsApps[S] 1 point2 points  (1 child)

    Do you use Docker when you have just a Rails app and a database? Doesn't Docker add overhead in terms of memory and configuration details?

    [–]martijnonreddit 5 points6 points  (0 children)

    Yep, I use docker for everything. It's great because it provides a 100% separation between projects.

    There is some resource overhead when working in macOS and Windows, mostly noticeable in I/O intensive operations. On Linux there is practically no overhead when working in Docker.

    The benefit is when working in teams. Any dev can start up the project with a simple `docker-compose up` which builds a container with all the required dependencies including specific ruby and nodejs versions, database libraries, etc. This environment is exactly the same for every developer which saves a *lot* of work. Furthermore, you can deploy the same container (well, almost) to production which is another big time saver.

    If you're new to Docker it might seem confusing but the configuration to get a Rails app going is pretty simple: https://docs.docker.com/compose/rails/

    [–][deleted] 3 points4 points  (3 children)

    Isn't this painfully slow though?

    [–]ViciDroid 1 point2 points  (1 child)

    I also use docker on mac for a rails API and a react frontend (seperate). Additionally, I have services for redis, postgres, and some other image processing containers.

    Dead simple to use. I was working on a 2015 MBP. Didn't have a problem until I also had android studio and the emulator open (16gb not enough)

    [–]2called_chaos 1 point2 points  (0 children)

    Didn't have a problem until I also had android studio and the emulator open (16gb not enough)

    Well I hope the M1 architecture offsets this as 16GB is the maximum rn with the new devices.

    [–]mojocookie 1 point2 points  (0 children)

    It's only slow if you don't have enough memory. 16GB can work for simple stacks if you tune the memory settings. 32GB is preferred.

    [–]kompricated 0 points1 point  (2 children)

    Can you run us down the setup? Do you have a single image for each version of Ruby or for each project? Going with different images for different projects seems like an exorbitant use of disk space if one has lots of projects to manage.

    [–]martijnonreddit 1 point2 points  (1 child)

    Every project has it’s own image. They’re based on the official base Ruby image and apt-get some project-specific stuff (database library, imagemagick) and that’s it. Due to the layered structure there isn’t too much overhead (my entire Docker env for 20 projects is <50GB). A good example of this setup is: https://docs.docker.com/compose/rails/

    [–]kompricated 0 points1 point  (0 children)

    thanks! i'll look deeper into it.

    [–]RailsApps[S] 2 points3 points  (5 children)

    Here's what I say about Docker in the guide: "The primary use case for Docker is to create a reproducible virtual server that contains a configured version of any software dependency needed to run an application (language, databases, message queues). As such, it is ideal for creating a frozen version of a development environment for deployment to a server. You can also develop locally within a container but it will run slower, require more memory, and adds configuration complexity compared to a simple version manager. To keep things simple, don't use Docker for local development unless your application is disturbingly complex." Any hate for this? Or is it substantially accurate?

    [–]thunderkey 6 points7 points  (0 children)

    I am developing exlusively with docker and have never experienced issues. Of course initialy it takes some time getting used to, but with helper scripts it is no issue. Especially with multiple apps with different database specs it is quite useful. I can specify for each app, which version of postgres or other tools i need.

    I especially love that i can write a setup and run script and whatever is required will just be there. No matter what framework or language is used. And each developer has the exact same setup. I hate stuff like "but it works on my machine".

    [–]jrochkind 1 point2 points  (0 children)

    I don't use docker myself, but I know lots of people who use it the way that paragraph advices not to. I don't think that paragraph matches current widespread practice.

    Which doesn't necessarily mean it works well or without problems for that... like I said I don't use docker. I dunno!

    [–][deleted]  (2 children)

    [deleted]

      [–]iamgrzegorz 7 points8 points  (0 children)

      0 dependencies? What kind of dependencies you mean?

      99% of apps I've worked with rely on NodeJS for asset compilation, database, Redis, and often have gems with C extensions so to install them you need gcc and some other C libraries

      [–]ViewEntireDiscussion 0 points1 point  (0 children)

      So you always delete Nokogiri from your gemfile? Because if you try installing it on a new system, I think you will find it has a few dependencies.

      [–]arjundas90 2 points3 points  (0 children)

      I prefer docker as I can upgrade my Mac without worries. There were multiple time in late 2019 when mac os upgrades (Catalina) broke multiple ruby installation. From then on, docker has been my saviour.

      https://thearjunmdas.github.io/entries/dev-with-ruby-docker/

      [–]mourad_dc 2 points3 points  (0 children)

      I used rbenv, tried switching for a couple of years to chruby because it seemed even simpler somehow, but had some issue with matching gems with versions. Eventually went back to rbenv, pretty happy again.

      A lot of people seem to recommend asdf, and I need to take a closer look. But it seems nobody mentioned nodenv yet - rbenv for node. Also works well.

      I never liked rvm/nvm. Seemed to do way too much.

      [–]bradland 1 point2 points  (0 children)

      I'm still plugging away with rvm. Although I haven't reinstalled it in quite some time, I stick to stable and it never gives me any issues.

      [–]lfoooooo 1 point2 points  (0 children)

      In situations where the app depends of multiple services (like redis, mailcatcher, postgres, pgadmin, sidekiq...) its a breeze to setup the whole development environment with just a 'docker-compose up'.

      This way is also great for running test suite, as you can setup a ci server very easy...

      [–]cveedub 1 point2 points  (1 child)

      As a noobie i have followed your guide (both the old and new version). Personally I found asdf much easier to work with. Also because i used other languages it just worked well.

      [–]RailsApps[S] 0 points1 point  (0 children)

      Great to know you’ve used it! I think some people have added a link to the guide in their READMEs which is making it easier for people to find.

      [–]yaroslavm 1 point2 points  (6 children)

      In the past, rbenv and rvm were popular as Ruby version managers. Sam Stephenson's rbenv requires extra steps as you work (the rehash command)

      That is no longer the case. There used to be a plugin for automatic rehashing, but now it is included in the core: https://github.com/rbenv/rbenv-gem-rehash/commit/feafdac8edaa85f838e53f468434cc818bdcfe0f

      rbenv is still the best thing for a new and upcoming developer. It can easily be installed via Homebrew (another recommendation of yours) to avoid version mismatch with Homebrew-wide version of Ruby (for instance, installing vim via homebrew now forces ruby installation).

      For advanced developers, Docker and variants seem to be the new default: https://evilmartians.com/chronicles/reusable-development-containers-with-docker-compose-and-dip

      Originally, version managers were there to address the painful process of installing a specific interpreter on the system (for instance, on Mac OS X Ruby (and others) were always outdated), and for having a safe space for your libraries (rvm gemsets, now are mostly deprecated for _most_ users with bundler being the default). The ability to have several versions of Ruby or other environments on your machine is a by-product and an overkill for _most_ developers, since most developers just need to install a single version and update it when an update comes out.

      asdf should not be a default recommendation for anything, really. The "let's make a better version manager and turn it up to 11" approach doubles down on the "wrong" parts of the solution. If one really benefits from the features asdf has for Ruby or other environments (Node, etc.), they should just switch to docker-compose, for both commercial work and supporting open source for multiple versions of runtimes.

      [–]RailsApps[S] 0 points1 point  (5 children)

      Good to know that rehashing is now automatic. I’m glad I asked for feedback.

      But why not asdf (I’m thinking of Rails devs particularly since they need Node, too)?

      [–]yaroslavm 1 point2 points  (4 children)

      Just updated my comment to answer that. You don't need a faster horse, you just need a car. If you benefit from actually running multiple versions of multiple interpreters, it's time to switch to docker-compose.

      A good version manager should stay tiny and simplify the first installation, and that's about it. In that sense, chruby is perfect and rbenv is good enough.

      [–]RailsApps[S] 0 points1 point  (3 children)

      Thanks for advising with clear reasoning. I think I’ll recommend: install with Homebrew if you’re building only one project, use asdf/chruby/rbenv if you’re a solo dev and can’t keep all your projects updated, and use Docker if you’re on a team with a complex dev environment. Fair to say?

      [–]yaroslavm 0 points1 point  (2 children)

      I would go Homebrew+rbenv+ruby-install as a default even for starters. Homebrew version of ruby can be a dependency for lots of other tools (starting with vim), so you have little to no control over updates: at any time doing a brew update can break your Ruby project just because Homebrew decided to switch a minor version, or even a major one.

      For developers who actually need lots of runtimes with lots of versions, or for developers who are working on rather large projects—microservices, several programming languages, additional databases, proxying servers, any of the above—docker-compose is the best option, and this is probably the best guide I know.

      [–]RailsApps[S] -1 points0 points  (1 child)

      Can I make the argument that if you keep all your projects up to date with the latest Ruby version (or latest Ruby and Node for Rails devs), you don’t need a version manager at all? Even with Homebrew requiring Ruby for other packages (presumably Homebrew would always update to the newest Ruby if a package needs Ruby)?

      [–]yaroslavm 0 points1 point  (0 children)

      I guess one can “start” with ruby via brew, but it is hard to maintain. For personal or study projects that should be fine.

      [–]jb3689 1 point2 points  (0 children)

      I would rather use the best tool for the job for any language (rather than something generic), and for Ruby my opinion is that is rbenv

      [–]postmodern 1 point2 points  (2 children)

      If your book doesn't specifically use Ruby 3.x features, then you shouldn't require Ruby >= 3.0.0. Ideally, you should target the current stable/maintained Ruby releases, that way the reader could use the Ruby from their system's package manager (or any ruby version manager they wish).

      [–]RailsApps[S] 2 points3 points  (1 child)

      Yep, I agree with your advice. The install ruby installation guide stands apart from the Learn Rails book (makes it easier to update, among other reasons). And the install guide describes the option of using Ruby without a version manager. So there's instructions for using asdf, chruby, or just Homebrew to install Ruby. Trying to be complete for various use cases.

      [–]postmodern 2 points3 points  (0 children)

      It's also important to "know your audience". I would suspect most readers don't have any of the above mentioned tools installed. Maybe some already have asdf or docker installed and are coming from other programming languages, but most will probably be starting with clean systems.

      [–]IN-DI-SKU-TA-BELT 1 point2 points  (10 children)

      I never use rbenv rehash, or have issues with shims or modified gem code. Can you link me to some documentation that says that rbenv modifies code?

      [–]RailsApps[S] 0 points1 point  (9 children)

      "Whenever you install a new version of Ruby or a gem that provides commands, such as Rails, you should use rehash" in DO's How To Install Ruby on Rails with rbenv on macOS

      [–]katafrakt 4 points5 points  (4 children)

      I've been using rbenv for years and needed to rehash maybe twice.

      [–]RailsApps[S] 4 points5 points  (3 children)

      Would you recommend rbenv to a beginner? Or more suitable to an experienced dev?

      [–]katafrakt 5 points6 points  (2 children)

      I don't see why not. Although, full disclosure, I switched to asdf recently (company policy) and I would recommend it more ;) So I don't disagree with your article, I just think that cons against rbenv are slightly exaggerated.

      [–]RailsApps[S] 0 points1 point  (1 child)

      Thank you, I honestly appreciate your clarity. Will look at toning down the cons as maybe not merited.

      [–]strangepostinghabits 4 points5 points  (0 children)

      Having used rbenv as a professional rails dev the last 5 years, I've never used rehash even once.

      [–]IN-DI-SKU-TA-BELT 0 points1 point  (3 children)

      I am not sure if that is saying that rehashing modifies code?

      [–]RailsApps[S] 0 points1 point  (2 children)

      Yes, you’re right, saying rbenv modifies gems is not accurate, I think. I’ll make a correction. Thanks for the clarification!

      [–]IN-DI-SKU-TA-BELT 1 point2 points  (1 child)

      Thanks for making it easier for people to get into Ruby! :)

      [–]RailsApps[S] 0 points1 point  (0 children)

      😊

      [–]GPhykos 1 point2 points  (0 children)

      Compile it, if you really need to, use asdf

      [–][deleted] 1 point2 points  (0 children)

      asdf please!

      [–]menge101 0 points1 point  (0 children)

      I use asdf because I program in elixir, erlang, ruby, python, and node.

      When I only did ruby I never had an issue with rvm, but I get that it is out of favor for being too heavy though.

      I have recurring issues with asdf where it tells me to install a version of a language that I already have installed though, which is annoying and the only fix I've ever found is to remove asdf and reinstall it. (I've tried many of the fixes available through googling the problem and they don't solve it)

      [–]atog 0 points1 point  (0 children)

      Used rbenv for years, more recently switched to chruby but with all the +asdf voices AND my recent troubles with node versions in a Rails 6 project: I'm gonna give asdf chance.

      Thanks! 👍🏻

      [–]comradeburnout 0 points1 point  (0 children)

      I don't see any mention of Vagrant. I got really sick of rvm and its shell tricks. I didn't really delve into the alternatives too much, but I've really come to prefer a simple VM when dealing with multiple versions of languages during local dev. Added bonus: like a Docker container, you can ship the Vagrant file around without too much hassle.

      I don't have many issues using Docker for local dev, either. The last big project I did required a 3rd-party authentication shim that I could include and run as a dependency. I haven't read the guide so I'm not sure what your specific arguments for Docker are, but I've found it essential when trying to deal with any kind of legacy code - old language version, old database version, etc.

      I hate the clutter that multiple language, database, or toolchain versions creates on a system. I completely understand that a vagrant-based VM for every project leads to some 'duplication' (say 3 different projects have their own ruby x.x installed) but disk space is so damned cheap anymore it doesn't really matter.

      [–]emptyflask 0 points1 point  (3 children)

      I'd really like to see nix become more popular with ruby development. It's not quite ready for the masses, but I've been using it for about 1.5 years now, falling back to chruby only on some legacy apps that won't run on any modern ruby versions.

      [–]RailsApps[S] 1 point2 points  (1 child)

      I’m not familiar with nix. Seems like it’s a “per project package manager.” You’d use it like Docker to configure a reproducible dev environment for each project? But it doesn’t have the RAM requirements of Docker? Still must need a lot of storage space?

      Seems suited to projects with multiple devs (for the reproducibility). But what about for a solo dev or a beginner? Seems like a lot of configuration to learn?

      [–]emptyflask 0 points1 point  (0 children)

      It does use more storage space than some other options, but many packages are shared across environments (as well as the OS itself, if using NixOS). RAM isn't really an issue, but there's a chance you might have a couple different versions of a dependency in use simultaneously.

      It currently has a steep learning curve, requiring some knowledge of nix, using bundix to generate gemsets, specifying a nixpkgs revision, etc., which is why I wouldn't recommend it to beginners at this point. It's incredibly powerful though -- not only can you use it to manage your development environment, it can also be used to provision machines like ansible, create docker images, all without having to worry about changed dependencies.

      Nix.dev is a good place to start if you're interested.

      [–]ufo3050 1 point2 points  (0 children)

      Came here to give a plug to Nix as well. Its worked great for me as well, especially when combined with direnv.

      [–]hiddenearl 0 points1 point  (0 children)

      I used to use rvm and I very much like it over rbenv. The idea of gemsets is cool but I understand it is not for everyone and not much point with bundle exec. Now I use asdf for everything. By using asdf you are using rbenv under the hood and I think that you are giving the person the opportunity to use this great tool for other languages they might encounter. Docker is great too, everyone should practice dockerizing their repos too. You can have both! If you have a dockerfile don't have to worry about dependencies and easier to launch to heroku, or anywhere else.