Ubuntu/Debian Üzerinde rbenv ile Çoklu Ruby Sürümü Yönetimi
Birden fazla Ruby projesi üzerinde çalışan her geliştiricinin ya da bu projeleri barındıran sistem yöneticisinin er ya da geç karşılaştığı problem şudur: Bir proje Ruby 2.7 isterken diğeri 3.2 istiyor, sistem Ruby’si ise ikisinden de farklı bir sürümde. İşte bu noktada rbenv devreye giriyor ve hayatı ciddi ölçüde kolaylaştırıyor. Bu yazıda Ubuntu ve Debian sistemlerde rbenv kurulumundan başlayıp, günlük sysadmin iş akışına entegre edecek düzeyde kullanımını ele alacağız.
rbenv Nedir, Neden rvm Değil?
Ruby dünyasında sürüm yönetimi için iki ana araç var: rvm ve rbenv. rvm yıllardır kullanılıyor ve kapsamlı özelliklere sahip, ama bu kapsamlılık beraberinde karmaşıklık getiriyor. Shell fonksiyonlarını override ediyor, cd gibi temel komutlara müdahale ediyor ve sistemin geri kalanıyla çakışma ihtimali oldukça yüksek.
rbenv ise Unix felsefesine daha uygun bir yaklaşım benimsiyor: Tek bir işi yap, onu iyi yap. rbenv temelde şimleri (shim) kullanıyor. Her Ruby komutu için /home/user/.rbenv/shims/ altında bir sarmalayıcı betik oluşturuyor. Bu betikler çalıştırıldığında rbenv hangi Ruby sürümünün kullanılacağına karar veriyor ve asıl komutu o sürümle çalıştırıyor. Sistem fonksiyonlarını kirletmiyor, kolayca kaldırılabiliyor ve anlaşılması çok daha basit.
Tek kullanıcılı geliştirici makinelerinde de, çok kullanıcılı üretim sunucularında da rbenv tercih etmemin ana nedeni bu temizlik.
Kurulum Öncesi Hazırlık
Ruby’yi kaynak koddan derleyeceğiz çünkü paket deposundaki sürümler genellikle güncel değil. Bu yüzden derleme bağımlılıklarını kurmamız gerekiyor.
sudo apt update && sudo apt upgrade -y
sudo apt install -y git curl build-essential libssl-dev
libreadline-dev zlib1g-dev libffi-dev libyaml-dev
libgdbm-dev libncurses5-dev automake libtool bison
libgmp-dev libdbm-dev
Bu paketlerin neden gerekli olduğuna kısaca bakalım:
- build-essential: gcc, make ve temel derleme araçlarını içeriyor
- libssl-dev: OpenSSL desteği için, olmadan HTTPS gem kurulumları başarısız olur
- libreadline-dev: IRB’de ok tuşlarıyla gezinme için
- zlib1g-dev: Gem dosyalarının sıkıştırma/açma işlemleri için
- libffi-dev: Native extension kullanan gemler için, Rails projelerde sık ihtiyaç duyulur
- libyaml-dev: YAML desteği, neredeyse her Ruby uygulaması için zorunlu
Bu adımı atlarsanız Ruby derlenirken ya da sonradan gem kurarken garip hatalar alırsınız. Özellikle libffi-dev eksikliği nedeniyle saatlerce debug yapan insanlar gördüm.
rbenv Kurulumu
İki farklı kurulum yöntemi var: Git ile manuel kurulum ve otomatik installer. Ben her zaman Git ile manuel kurulumu tercih ediyorum çünkü tam olarak ne kurduğumu biliyorum.
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
# Performans için C extension'ları derliyoruz (isteğe bağlı ama önerilen)
cd ~/.rbenv && src/configure && make -C src 2>/dev/null || true
Şimdi PATH ayarlarını yapıyoruz. Hangi shell kullandığınıza göre doğru dosyayı düzenleyin:
# Bash kullananlar için
echo 'export RBENV_ROOT="$HOME/.rbenv"' >> ~/.bashrc
echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc
# Zsh kullananlar için ~/.zshrc dosyasına ekleyin
echo 'export RBENV_ROOT="$HOME/.rbenv"' >> ~/.zshrc
echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc
# Değişiklikleri uygulayın
source ~/.bashrc
ruby-build eklentisini kuruyoruz. Bu eklenti olmadan rbenv install komutu çalışmaz:
git clone https://github.com/rbenv/ruby-build.git
"$(rbenv root)/plugins/ruby-build"
Kurulumun doğru çalışıp çalışmadığını kontrol edelim:
rbenv --version
# Çıktı: rbenv 1.x.x
type rbenv
# Çıktı: rbenv is a function (bu önemli, "file" değil "function" görmek istiyoruz)
Ruby Sürümü Kurma
Mevcut kurulabilir sürümleri listelemek için:
rbenv install --list
# Sadece kararlı sürümleri listeler
rbenv install --list-all
# Tüm mevcut sürümleri listeler, çıktı çok uzun olur
Şimdi birkaç farklı Ruby sürümü kuralım. Derleme işlemi makineye göre 5-15 dakika sürebilir:
# Ruby 3.2.x kuruyoruz (x yerine listedeki en güncel patch versiyonu)
rbenv install 3.2.4
# Eski bir proje için Ruby 2.7.x
rbenv install 2.7.8
# Kurulum sırasında çıktıyı görmek istiyorsanız verbose flag kullanın
rbenv install -v 3.1.6
Kurulu sürümleri görmek için:
rbenv versions
# Çıktı:
# system
# 2.7.8
# 3.1.6
# * 3.2.4 (set by /home/kullanici/.rbenv/version)
Yıldız işareti aktif olan sürümü gösteriyor. system ise Ubuntu’nun paket deposundan kurulu Ruby’yi temsil ediyor.
Global, Local ve Shell Sürümü Kavramları
rbenv üç seviyede sürüm belirlemenize izin veriyor. Bu hiyerarşiyi anlamak kritik öneme sahip.
Global sürüm tüm sistem genelinde varsayılan olarak kullanılan sürümdür. ~/.rbenv/version dosyasında saklanır:
rbenv global 3.2.4
ruby --version
# ruby 3.2.4 (2024-04-23 revision 6431e894e5) [x86_64-linux]
Local sürüm belirli bir dizin için geçerlidir. Proje dizininde .ruby-version dosyası oluşturur ve o dizinde çalışırken otomatik olarak devreye girer:
cd /var/www/eski-proje
rbenv local 2.7.8
cat .ruby-version
# 2.7.8
ruby --version
# ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [x86_64-linux]
cd ~
ruby --version
# global sürüme döner: ruby 3.2.4
Bu özellik gerçekten çok güçlü. Proje klasörüne girdiğinizde otomatik olarak doğru Ruby sürümüne geçiş yapıyor. .ruby-version dosyasını Git reposuna dahil etmenizi öneririm, böylece ekipteki herkes aynı sürümü kullanır.
Shell sürümü sadece mevcut terminal oturumu için geçerlidir. Hızlı testler yapmak istediğinizde işe yarıyor:
rbenv shell 3.1.6
ruby --version
# ruby 3.1.6
# Sıfırlamak için
rbenv shell --unset
Shim Mekanizması ve Rehashing
rbenv yeni bir Ruby sürümü kurduğunuzda veya yeni bir gem eklediğinizde shims dizinini güncellemeniz gerekiyor. Eski rbenv sürümlerinde bu manuel olarak yapılıyordu:
rbenv rehash
Modern rbenv sürümlerinde bu işlem otomatik gerçekleşiyor ama bir şeylerin yanlış gittiğini düşünüyorsanız manuel olarak çalıştırabilirsiniz. Örneğin yeni bir gem kurduğunuzda komut bulunamıyor gibi bir hata alırsanız ilk yapmanız gereken şey rbenv rehash çalıştırmak.
Hangi Ruby’nin kullanıldığını ve neden o sürümün seçildiğini anlamak için:
rbenv which ruby
# /home/kullanici/.rbenv/versions/3.2.4/bin/ruby
rbenv version
# 3.2.4 (set by /var/www/proje/.ruby-version)
Gem Yönetimi ile Entegrasyon
Her Ruby sürümü kendi gem deposuna sahip. Bu sayede farklı projeler arasında gem sürümü çakışması yaşanmıyor. Bir sürüm için gem kurduğunuzda diğer sürümler etkilenmiyor:
# 3.2.4 sürümü için gem kur
rbenv shell 3.2.4
gem install bundler rails
# 2.7.8 için ayrı gem ortamı
rbenv shell 2.7.8
gem install bundler -v 2.3.26
# Her sürümün gem listesi bağımsız
gem list | grep bundler
Gerçek dünya projelerinde Bundler ile çalışacaksınız. rbenv ile Bundler mükemmel uyum içinde çalışıyor:
cd /var/www/rails-projesi
# .ruby-version dosyası mevcut, doğru Ruby otomatik seçildi
bundle install
bundle exec rails server
bundle exec kullanmak önemli. Bu komut gemlerinizi projenin Gemfile.lock dosyasına göre yükleyip çalıştırıyor ve başka projelerle izolasyon sağlıyor.
Gerçek Dünya Senaryosu: Çok Projeli Sunucu Yapılandırması
Bir üretim sunucusunda birden fazla Ruby on Rails uygulaması barındırdığınızı düşünelim. Biri legacy uygulama Ruby 2.7 ile çalışıyor, diğerleri daha güncel sürümler istiyor.
# Dizin yapısı
# /var/www/legacy-app -> Ruby 2.7.8
# /var/www/modern-app -> Ruby 3.2.4
# /var/www/api-service -> Ruby 3.1.6
# Her proje kendi .ruby-version dosyasına sahip
echo "2.7.8" > /var/www/legacy-app/.ruby-version
echo "3.2.4" > /var/www/modern-app/.ruby-version
echo "3.1.6" > /var/www/api-service/.ruby-version
# Deployment script örneği
cd /var/www/modern-app
rbenv version # 3.2.4 olduğunu doğrula
bundle install --deployment
bundle exec rake db:migrate
bundle exec rails assets:precompile
Systemd servis dosyalarında rbenv kullanırken dikkat etmeniz gereken bir noktar var. Systemd servisleri shell profilini yüklemediği için PATH ayarlarınız geçerli olmaz:
# /etc/systemd/system/rails-app.service
# [Service] bölümüne şunları ekleyin:
cat > /etc/systemd/system/rails-modern.service << 'EOF'
[Unit]
Description=Rails Modern App
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/var/www/modern-app
Environment=RBENV_ROOT=/home/deploy/.rbenv
Environment=PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/home/deploy/.rbenv/shims/bundle exec puma -C config/puma.rb
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable rails-modern
systemctl start rails-modern
Sistem Genelinde rbenv Kurulumu
Birden fazla kullanıcının aynı Ruby sürümlerini kullanacağı sunucularda her kullanıcı için ayrı ayrı kurulum yapmak yerine sistem genelinde kurulum yapabilirsiniz:
# root olarak veya sudo ile
sudo git clone https://github.com/rbenv/rbenv.git /usr/local/rbenv
sudo git clone https://github.com/rbenv/ruby-build.git /usr/local/rbenv/plugins/ruby-build
# Sistem genelinde profile dosyası oluştur
sudo tee /etc/profile.d/rbenv.sh << 'EOF'
export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
EOF
sudo chmod +x /etc/profile.d/rbenv.sh
# Bu dosyayı source edelim
source /etc/profile.d/rbenv.sh
# Ruby kur
sudo RBENV_ROOT=/usr/local/rbenv rbenv install 3.2.4
sudo RBENV_ROOT=/usr/local/rbenv rbenv global 3.2.4
Sistem genelinde kurulumda dikkat edilmesi gereken nokta: gem kurulumları için yazma izni gerekiyor. Bu durumda ya sudo gem install kullanmanız ya da kullanıcıların kendi gem dizinlerini yapılandırması gerekiyor.
ruby-build Güncelleme
Yeni Ruby sürümleri çıktıkça ruby-build eklentisini güncellemeniz gerekiyor. Aksi takdirde rbenv install --list komutunda yeni sürümler görünmez:
cd "$(rbenv root)/plugins/ruby-build"
git pull
# Güncelleme sonrası yeni sürümleri görebilirsiniz
rbenv install --list
Sorun Giderme
Kurulum veya kullanım sırasında karşılaşılan yaygın sorunlar ve çözümleri:
“rbenv: command not found” hatası
Bu genellikle PATH ayarları yanlış yapıldığında ya da shell yeniden başlatılmadığında oluşur:
# Terminali kapatıp açın ya da
exec $SHELL -l
# Hala sorun varsa
echo $PATH | tr ':' 'n' | grep rbenv
# Çıktıda rbenv yolunu görmelisiniz
Derleme hatası: “configure: error: OpenSSL library not found”
sudo apt install -y libssl-dev
# Ubuntu 22.04+ için bazen OpenSSL 3 uyumsuzluğu yaşanır
# Eski Ruby sürümleri için:
RUBY_CONFIGURE_OPTS=--with-openssl-dir=/usr rbenv install 2.7.8
“You don’t have write permissions” gem kurulum hatası
# Doğru Ruby sürümünün aktif olduğunu kontrol edin
rbenv version
which gem
# /home/kullanici/.rbenv/shims/gem görmeli, /usr/bin/gem değil
Bundler sürüm uyumsuzluğu
# Gemfile.lock içindeki bundler sürümünü kur
gem install bundler -v $(cat Gemfile.lock | grep "BUNDLED WITH" -A 1 | tail -1 | tr -d ' ')
rbenv Eklentileri
rbenv tek başına oldukça minimal. Yaygın kullanılan birkaç eklenti:
- ruby-build: Ruby sürümlerini derleme ve kurma, zaten kurulu olması şart
- rbenv-vars: Proje bazlı ortam değişkenleri için
.rbenv-varsdosyası desteği, hassas veriler için işe yarar - rbenv-default-gems: Yeni Ruby sürümü kurulduğunda otomatik gem kurulumu, bundler her zaman yüklensin isteyenler için ideal
- rbenv-each: Tüm kurulu Ruby sürümlerinde aynı komutu çalıştırma, toplu gem güncellemeleri için kullanışlı
rbenv-default-gems kurulumu:
git clone https://github.com/rbenv/rbenv-default-gems.git
"$(rbenv root)/plugins/rbenv-default-gems"
# Otomatik kurulacak gemleri belirt
cat > "$(rbenv root)/default-gems" << EOF
bundler
rubocop
solargraph
EOF
Artık her yeni Ruby kurulumunda bu gemler otomatik olarak yüklenecek.
Performans ve Günlük Kullanım İpuçları
Uzun süredir rbenv kullanan biri olarak birkaç pratik öneri:
Shell başlangıç süresini optimize etmek için eval "$(rbenv init -)" ifadesi zaman alabilir. Alternatif olarak lazy loading yapabilirsiniz ama bu konuda işleri karmaşıklaştırmamayı tercih ediyorum, fark günlük kullanımda hissedilir seviyede değil.
CI/CD pipeline’larınızda .ruby-version dosyasını kullanın. GitHub Actions, GitLab CI ve CircleCI bu dosyayı otomatik olarak okuyabilen setup-ruby gibi action’lara sahip. Böylece geliştirici makinesi, CI ortamı ve üretim sunucusu aynı Ruby sürümünü kullanır.
# Mevcut projedeki Ruby sürümünü hızlıca kontrol
cat .ruby-version 2>/dev/null || rbenv version
# Tüm projelerin Ruby sürümlerini listele
find /var/www -name ".ruby-version" -exec echo "=== {} ===" ; -exec cat {} ;
Sonuç
rbenv, Ruby sürüm yönetiminde sade ve güvenilir bir çözüm sunuyor. Sistem bütünlüğünü bozmadan birden fazla Ruby sürümünü aynı anda barındırabiliyorsunuz, proje bazlı otomatik sürüm değişimi çalışma akışını son derece akıcı hale getiriyor. Özellikle birden fazla Ruby projesi barındıran sunucularda ve heterojen geliştirme ortamlarında rbenv’in değeri tartışmasız.
Kurulumdan sonra yapmanız gereken en önemli şey .ruby-version dosyalarını projelerinize eklemek ve ekibin tamamının aynı araçları kullanmasını sağlamak. Bu küçük disiplin, “bende çalışıyor” sorunlarının büyük çoğunluğunu ortadan kaldırıyor. ruby-build eklentisini düzenli güncellemek de yeni sürümlere erişebilmek için kritik, aylık bir hatırlatıcı kurmanızı öneririm.
Sistemde yer kaplayan ve artık kullanmadığınız Ruby sürümlerini rbenv uninstall 2.6.10 komutuyla temizlemeyi de unutmayın; her Ruby sürümü gemlerle birlikte birkaç yüz megabayt yer tutabiliyor.
