Ubuntu’ya Ruby Kurulumu: rbenv ve RVM Karşılaştırması
Ubuntu üzerinde Ruby kurulumu ilk bakışta basit gibi görünse de, birden fazla proje üzerinde çalışan bir sysadmin veya geliştirici için versiyon yönetimi ciddi bir sorun haline gelebilir. Bir proje Ruby 2.7 isterken diğeri 3.2 gerektiriyorsa, sistem genelinde tek bir Ruby kurulumu tam anlamıyla kaosa davet çıkarmak demektir. İşte tam bu noktada rbenv ve RVM devreye giriyor. Bu yazıda her iki aracı da gerçek dünya senaryolarıyla inceleyeceğiz, hangi durumda hangisini kullanmanız gerektiğini netleştireceğiz ve kurulumdan üretim ortamına kadar tüm süreci adım adım ele alacağız.
Sistem Paket Yöneticisiyle Ruby Kurulumu ve Neden Yetmez
Ubuntu’da apt install ruby komutu işe yarar ama çoğu zaman işe yaramaz. Yani teknik olarak Ruby kurulur, ama depodaki versiyon genellikle güncel değildir. Ubuntu 22.04 LTS’in resmi deposunda Ruby 3.0 bulunurken, Ruby’nin mevcut kararlı sürümü çoktan 3.3.x bandına geçmiştir.
# Sistem deposundan Ruby kurulumu (önerilmez, sadece görmek için)
sudo apt update
sudo apt install ruby ruby-dev
ruby --version
# Çıktı: ruby 3.0.2p107 (muhtemelen)
Bunun yanı sıra sistem Ruby’si /usr/lib/ruby altına kurulur ve gem kurulumları için sürekli sudo kullanmanız gerekir. Bu da izin sorunlarına, kırık gem bağımlılıklarına ve farklı projeler arasında sürüm çakışmalarına zemin hazırlar. Üretim sunucularında ise bu durum daha da kritik hale gelir.
rbenv Nedir, Nasıl Çalışır?
rbenv, Ruby versiyonlarını yönetmek için tasarlanmış hafif bir araçtır. Temel felsefesi son derece minimalist: Ruby kurulumu yapmaz, sadece hangi Ruby versiyonunun kullanılacağını belirler. Ruby’yi asıl kuran eklenti ruby-build‘dir.
rbenv’in çalışma mantığı “shim” adı verilen ince sarmalayıcı dosyalara dayanır. PATH değişkeninin başına rbenv’in shim dizinini ekler. ruby komutu çalıştırıldığında önce bu shim devreye girer, aktif Ruby versiyonunu belirler ve gerçek Ruby binary’sine yönlendirir. Bu yüzden rbenv son derece az sistem kaynağı tüketir ve mevcut shell ortamına minimum müdahale eder.
rbenv Kurulumu
Önce gerekli bağımlılıkları kuralım:
sudo apt update
sudo apt install -y git curl libssl-dev libreadline-dev zlib1g-dev
autoconf bison build-essential libyaml-dev libreadline-dev
libncurses5-dev libffi-dev libgdbm-dev
rbenv’i GitHub’dan klonlayarak kuruyoruz:
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
# ruby-build eklentisini de kuruyoruz
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
# Shell konfigürasyonuna ekliyoruz (bash için)
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
# Kurulumu doğrulayalım
rbenv --version
Eğer Zsh kullanıyorsanız .bashrc yerine .zshrc dosyasını düzenlemeniz gerektiğini hatırlatalım.
rbenv ile Ruby Kurulumu
# Mevcut kurulabilir versiyonları listele
rbenv install --list
# Belirli bir versiyon kur
rbenv install 3.3.0
rbenv install 3.1.4
# Global (sistem geneli) versiyonu ayarla
rbenv global 3.3.0
# Sadece o an bulunduğunuz dizin için versiyon ayarla
cd /var/www/myapp
rbenv local 3.1.4
# Aktif versiyonu kontrol et
ruby --version
# Kurulu tüm versiyonları listele
rbenv versions
rbenv local komutu çalıştırıldığında, proje dizinine .ruby-version adlı bir dosya oluşturur. Bu dosya git’e commit edilebilir ve ekipteki herkes aynı Ruby versiyonunu otomatik olarak kullanır. Sysadmin açısından bakıldığında bu özellik son derece değerlidir.
Gerçek Dünya Senaryosu: Çoklu Rails Projesi
Diyelim ki bir sunucuda iki farklı Rails uygulaması çalıştırıyorsunuz. Birincisi eski bir müşteri projesi Ruby 2.7 gerektiriyor, ikincisi aktif geliştirme altındaki yeni proje Ruby 3.3 kullanıyor.
# Eski proje dizini
cd /var/www/legacy-app
rbenv local 2.7.8
ruby --version # ruby 2.7.8
# Yeni proje dizini
cd /var/www/new-app
rbenv local 3.3.0
ruby --version # ruby 3.3.0
# Otomatik geçiş çalışıyor mu diye kontrol
cd /var/www/legacy-app
ruby --version # Tekrar 2.7.8 döner
Bu senaryoda her şey otomatik çalışır. Dizinler arasında geçiş yaptığınızda rbenv .ruby-version dosyasını okuyarak aktif versiyonu değiştirir. Hiçbir source komutu, hiçbir manuel müdahale gerekmez.
RVM Nedir, Nasıl Çalışır?
RVM (Ruby Version Manager), rbenv’den çok önce ortaya çıkmış ve uzun süre sektörün standart aracı olmuş kapsamlı bir versiyon yöneticisidir. rbenv’in aksine RVM yalnızca versiyon yönetimi yapmaz; gemset yönetimi, otomatik gemset geçişi ve birçok ek özellik sunar.
RVM’nin çalışma mekanizması rbenv’den temelden farklıdır. Shell fonksiyonlarını override eder, cd komutu gibi temel shell işlevlerini bile değiştirebilir. Bu “saldırgan” yaklaşım bazı güç özelliklerin önünü açar ama aynı zamanda daha karmaşık bir yapı anlamına gelir.
RVM Kurulumu
RVM’nin kendi kurulum betiği vardır:
# GPG anahtarlarını içe aktar
gpg --keyserver keyserver.ubuntu.com --recv-keys
409B6B1796C275462A1703113804BB82D39DC0E3
7D2BAF1CF37B13E2069D6956105BD0E739499BDB
# RVM'yi kur
curl -sSL https://get.rvm.io | bash -s stable
# Shell'i yeniden başlat veya source et
source ~/.rvm/scripts/rvm
# Kurulumu doğrula
rvm --version
RVM kurulumu sırasında ~/.rvm dizinine tüm dosyaları indirir, oldukça kapsamlı bir kurulum yapar. Kurulum bittiğinde .bashrc veya .bash_profile dosyalarını otomatik olarak düzenler.
RVM ile Ruby Kurulumu ve Gemset Yönetimi
# Ruby kur
rvm install 3.3.0
rvm install 3.1.4
# Varsayılan versiyonu ayarla
rvm use 3.3.0 --default
# Gemset oluştur (RVM'nin güçlü özelliği)
rvm gemset create myapp-production
rvm gemset create myapp-development
# Belirli bir versiyon ve gemset ile çalış
rvm use 3.3.0@myapp-production
gem list
# Aktif gemset ve versiyon bilgisi
rvm info
RVM’nin gemset özelliği, aynı Ruby versiyonu altında birden fazla izole gem ortamı yaratmanıza olanak tanır. Bu özellik özellikle aynı Ruby versiyonunu kullanan ama farklı gem bağımlılıklarına sahip projelerde işe yarar.
RVM ile .rvmrc Kullanımı
# Proje dizinine .rvmrc dosyası oluştur
cd /var/www/myapp
echo 'rvm use 3.3.0@myapp --create' > .rvmrc
# Dizine ilk girişte onay ister
cd /var/www/myapp
# "Do you wish to trust this .rvmrc file?" sorusunu onaylıyorsunuz
# Artık dizine her girdiğinizde otomatik geçiş yapar
Modern RVM kullanımında .ruby-version ve .ruby-gemset dosyaları da desteklenir, bu da rbenv ile bir miktar uyumluluk sağlar.
rbenv ve RVM: Hangi Kriterlerde Farklılaşıyor?
Kurulum Karmaşıklığı ve Sistem Etkisi
rbenv kurulumu son derece basittir. Birkaç git clone komutu ve iki satır shell konfigürasyonu yeterlidir. Kaldırmak istediğinizde ~/.rbenv dizinini silip shell konfigürasyonundaki iki satırı kaldırmanız yeterlidir. Sistemde iz bırakmaz.
RVM ise daha agresif bir kurulum yapar. Shell fonksiyonlarını override eder, bazı durumlarda sistem paketlerini yeniden derleyebilir. Sunucu ortamlarında bu beklenmedik yan etkilere yol açabilir.
Performans Farkı
rbenv’in shim tabanlı yapısı çok hafiftir. Her komut çalıştırmasında minimal bir overhead vardır ve bu pratikte hiç hissedilmez.
RVM’nin shell fonksiyon override yaklaşımı teorik olarak biraz daha fazla kaynak kullanır, ancak modern sistemlerde bu fark da pratikte ihmal edilebilir düzeydedir.
Gemset Yönetimi
Bu konuda RVM açıkça öne çıkar. rbenv’de gemset benzeri bir özellik için rbenv-gemset eklentisini ayrıca kurmanız gerekir veya Bundler kullanarak her projeye özel gem dizini yaratmanız gerekir ki zaten modern Ruby geliştirmede Bundler standart hale gelmiştir.
# Bundler ile proje bazlı gem izolasyonu (rbenv ile birlikte önerilen yol)
cd /var/www/myapp
bundle config set --local path 'vendor/bundle'
bundle install
# Artık gemler vendor/bundle altına kurulur
bundle exec rails server
Bundler’ın yaygınlaşmasıyla birlikte RVM’nin gemset özelliğinin önemi azalmıştır. Çoğu modern Rails ve Ruby projesi zaten Bundler üzerinden gem yönetimi yapar.
Güvenlik Değerlendirmesi
rbenv güvenlik açısından daha temiz bir profile sahiptir. Sistem genelinde değişiklik yapmaz, root yetkisi gerektirmez ve kurulum betiği çalıştırmak yerine git clone kullanır.
RVM’nin kurulum betiğinin doğrudan curl | bash ile çalıştırılması güvenlik açısından dikkat gerektiren bir yaklaşımdır. GPG doğrulaması bu riski azaltsa da, sysadmin olarak bu noktayı göz ardı etmemek gerekir.
Üretim Sunucusu Senaryosu: Nginx + Puma + rbenv
Gerçek bir production senaryosunu ele alalım. Bir Rails uygulamasını Ubuntu 22.04 üzerinde Nginx ve Puma ile çalıştıracağız, Ruby versiyon yönetimi için rbenv kullanacağız.
# Deploy kullanıcısı oluştur
sudo adduser deployer
sudo usermod -aG sudo deployer
su - deployer
# rbenv kurulumu (deployer kullanıcısı için)
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
# Ruby kur
rbenv install 3.3.0
rbenv global 3.3.0
# Bundler kur
gem install bundler --no-document
# Uygulama dizini
mkdir -p /var/www/myapp
cd /var/www/myapp
# .ruby-version dosyası zaten git reposunda mevcut olacak
Systemd service dosyası için rbenv yolunu doğru belirtmek kritik önem taşır:
# /etc/systemd/system/myapp.service
sudo tee /etc/systemd/system/myapp.service > /dev/null <<EOF
[Unit]
Description=Puma HTTP Server for MyApp
After=network.target
[Service]
Type=notify
WatchdogSec=10
User=deployer
WorkingDirectory=/var/www/myapp
Environment=RBENV_ROOT=/home/deployer/.rbenv
Environment=PATH=/home/deployer/.rbenv/shims:/home/deployer/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
ExecStart=/home/deployer/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -TSTP $MAINPID
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
Bu noktada dikkat edilmesi gereken en önemli şey, systemd servisinin kendi ortam değişkenleri olduğu için rbenv’in PATH manipülasyonunun otomatik çalışmadığıdır. Environment=PATH satırında rbenv shim dizinini açıkça belirtmek zorunludur.
rbenv ile Ekip Ortamında Standart Sağlamak
Bir geliştirme ekibinde herkesin aynı Ruby versiyonunu kullanmasını sağlamak sysadmin sorumluluklarından biridir. rbenv bu konuda oldukça yardımcıdır.
# Her projenin kök dizininde .ruby-version dosyası bulunmalı
cat /var/www/myapp/.ruby-version
# 3.3.0
# Bu dosya git'e commit edilmeli
cd /var/www/myapp
git add .ruby-version
git commit -m "Ruby 3.3.0 versiyonu belirlendi"
# Yeni bir geliştirici projeyi clone ettiğinde
git clone https://github.com/sirket/myapp.git
cd myapp
# rbenv otomatik olarak .ruby-version'u okur
ruby --version # 3.3.0 değilse uyarı verir
# Eksik versiyon kurulumu
rbenv install # .ruby-version'daki versiyonu otomatik kurar
CI/CD pipeline’larında da bu dosya kritik rol oynar. GitHub Actions veya GitLab CI gibi ortamlarda rbenv kurulumu otomatikleştirilebilir ve her build tam olarak doğru Ruby versiyonuyla çalışır.
Sorun Giderme: Sık Karşılaşılan Hatalar
rbenv’de “command not found” Hatası
# Shell konfigürasyonu doğru yüklenmiş mi kontrol et
echo $PATH | tr ':' 'n' | grep rbenv
# Yoksa yeniden yükle
source ~/.bashrc
# Veya tam yol ile çalıştır
~/.rbenv/bin/rbenv versions
RVM’de “RVM is not a function” Hatası
# RVM script'ini source et
source ~/.rvm/scripts/rvm
# .bashrc'de bu satırın var olduğunu doğrula
grep -n 'rvm' ~/.bashrc
# Bazı sistemlerde .bash_profile gerekebilir
source ~/.bash_profile
Ruby Derleme Hataları
Her iki araçta da Ruby kaynaktan derlenir. Eksik sistem kütüphaneleri derlemeyi bozar:
# Eksik bağımlılıkları kur
sudo apt install -y libssl-dev libreadline-dev zlib1g-dev
libffi-dev libyaml-dev
# Derleme önbelleğini temizle ve yeniden dene
rbenv install --force 3.3.0
Hangisini Seçmeli?
Bu sorunun net bir cevabı vardır ve tercihler zamanla değişmiştir. Sektörün genel eğilimi rbenv yönünde kaymaktadır, bunun birkaç temel nedeni vardır.
rbenv tercih etmenizi önerdiğim durumlar:
- Yeni bir kurulum yapıyorsanız
- Üretim sunucularında temiz ve tahmin edilebilir bir ortam istiyorsanız
- Docker veya container ortamlarında çalışıyorsanız
- Ekip genelinde standart bir yapı oluşturmak istiyorsanız
- Gemset yönetimini Bundler üzerinden yapmayı tercih ediyorsanız
RVM’yi değerlendirebileceğiniz durumlar:
- Mevcut bir RVM kurulumunu koruyorsanız ve geçiş maliyeti yüksekse
- Bundler kullanmadan gemset izolasyonu yapmanız gerekiyorsa
- RVM’nin gelişmiş otomatik geçiş özelliklerine ihtiyaç duyuyorsanız
Fark edilecek bir nokta: RVM’yi sıfırdan kurmayı önerdiğim bir senaryo neredeyse yok denecek kadar azdır. Modern Ruby ekosistemine bakıldığında rbenv ve Bundler kombinasyonu tüm ihtiyaçları karşılamakta, RVM’nin getirdiği ek karmaşıklık ise çoğu durumda karşılığını bulmamaktadır.
Sonuç
Ubuntu’da Ruby versiyon yönetimi konusunda hem rbenv hem de RVM işlevsel araçlardır, ancak aralarındaki fark gün geçtikçe daha belirginleşmektedir. rbenv’in minimal ve Unix felsefesine uygun yaklaşımı, özellikle üretim ortamları ve ekip çalışması açısından daha güvenilir ve yönetilebilir bir yapı sunar. RVM köklü ve özellik zengini bir araç olmaya devam etmektedir, ancak Bundler’ın gemset ihtiyacını karşılaması ve rbenv’in sadeliğiyle öne çıkması RVM’nin kullanım alanını daraltmıştır.
Yeni bir Ubuntu sunucusu kuruyor ve Ruby ortamı hazırlıyorsanız, rbenv ile başlayın. Deployer kullanıcısı oluşturun, rbenv’i kullanıcı bazında kurun, .ruby-version dosyalarını git’e commit edin, Bundler ile gem izolasyonunu sağlayın. Systemd servislerinde PATH’i açıkça belirtin. Bu yapı sizi hem geliştirme hem de üretimde uzun vadede sorunsuz çalıştıracak, versiyon geçişlerini basit tutacak ve ekip içi tutarlılığı garanti altına alacaktır.
