Ubuntu 24.10 VPS with Low (1GB) Ram freezes during build of YJIT on ruby-3.3.0 install
Steps to reproduce the behavior
Start a new digital ocean VPS/droplet on Ubuntu 24.10, with 1GB of ram or less. Install dependencies
sudo apt update && apt upgrade
apt-get install autoconf patch build-essential rustc libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev
apt install libpq-dev
apt install rbenv
rbenv init
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
reconnect to server...
rbenv install 3.3.0 --verbose
Build freezes at building Rust YJIT (see logs)
Temp file system is at half usage.
df -h /tmp
Filesystem Size Used Avail Use% Mounted on
tmpfs 481M 257M 224M 54% /tmp
Expected vs. actual behavior
Expected behavior: Using a lower than recommended amount of ram, expected a message that lets me know why the build is frozen or will not complete.
Actual behavior:
Build freezes and doesnt complete. If using non-verbose mode, the build appears stuck at
make -j 1 and there are no logs. The only way out is to cancel the build and manually increase /tmp/ (see the solution below)
Logs
rbenv install 3.3.0 --verbose got stuck here
building Rust YJIT (release mode)
warning: unused import: `condition::Condition`
--> ./yjit/src/asm/arm64/arg/mod.rs:13:9
|
13 | pub use condition::Condition;
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `rb_yjit_fix_mul_fix as rb_fix_mul_fix`
--> ./yjit/src/cruby.rs:188:9
|
188 | pub use rb_yjit_fix_mul_fix as rb_fix_mul_fix;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> ./yjit/src/core.rs:982:49
|
982 | formatter.debug_list().entries(branches.into_iter()).finish()
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: `#[warn(boxed_slice_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
982 | formatter.debug_list().entries(branches.iter()).finish()
| ~~~~
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
|
982 | formatter.debug_list().entries(IntoIterator::into_iter(branches)).finish()
| ++++++++++++++++++++++++ ~
Solution
Use a VPS with 2GB of ram.
Or follow these steps if you're trying to save money:
Preparing to try install of ruby-3.3.0 again by wiping /tmp...
disclaimer: I dont know how bad it is to run rm -rf /tmp/, but it's probably bad practice
rm -rf /tmp
rm: cannot remove '/tmp': Device or resource busy
Manually adding a swapfile and increasing available tmp space with virtual ram:
sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=1024
sudo mkswap /mnt/swapfile
sudo swapon /mnt/swapfile
Then increase tempfs size:
mount -o remount,size=1G /tmp/
df -h /tmp/
Filesystem Size Used Avail Use% Mounted on
tmpfs 1.0G 0 1.0G 0% /tmp
Attempt install of ruby-3.3.0 again
rbenv install 3.3.0 --verbose
It should succeed this time
==> Installed ruby-3.3.0 to /root/.rbenv/versions/3.3.0
NOTE: to activate this Ruby version as the new default, run: rbenv global 3.3.0
root@ubuntu-s-1vcpu-1gb-nyc1-01:~# rbenv versions
* system (set by /root/.rbenv/version)
3.3.0
It should succeed this time, but if doesnt, I tried these steps a few days ago (Mar 22) and this would still not work because Ubuntu 24.10 shipped with an older version of rustc. So I needed to manually install the latest rustup with these steps:
sudo apt remove rustc
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
add to PATH:
source "$HOME/.cargo/env"
Cleanup:
Turn off the swapfile
sudo swapoff /mnt/swapfile
Remount /tmp/ filesystem to original size
mount -o remount,size=481M /tmp/
check /tmp/ is configured with origin size
root@ubuntu-s-1vcpu-1gb-nyc1-01:~# df -h /tmp/
Filesystem Size Used Avail Use% Mounted on
tmpfs 481M 0 481M 0% /tmp
Hi, thank you for detailed description of the problem and also sharing how you solved it.
Unfortunately, from user reports such as yours it is known that machines with low RAM have trouble compiling Ruby, but neither ruby-build (this project) nor Ruby itself have any detection of this being the case, primarily because this would be hard to maintain cross-platform. Our wiki has a note about temporarily resizing the /tmp partition, but I'm not sure how discoverable that is: https://github.com/rbenv/ruby-build/wiki#no-space-left-on-device
I agree that the build process freezing up with no error message nor other kind of explanation is bad user experience, but this is also something that is technically hard to solve. @hsbt: Would you think that this (i.e. low RAM scenarios) is something that Ruby's build system could potentially handle better?
BTW, what was the error message you got due to using the outdated version of rustc from Ubuntu's own repository? Also, due to having multiple issues with YJIT, was it an option for you to disable it? I think something like this would have worked:
rbenv install 3.3.0 --verbose -- --disable-yjit
@mislav thank you for the information. Hear you on the difficulty of implementing cross platform RAM usage/status. On the discoverability of this issue, unfortunately searching the web for "no space left on device ruby-build when installing ruby" results in older unrelated issues, so the solution you shared this repository in the ruby-build wiki didnt show up.
I tried to reproduce the rustc version issue I encountered. This was when I began installing with very minimal dependencies in the apt install list. This can actually succeed on Ubuntu 24.10 by only updating the system and then installing rbenv, given the RAM is sufficient.
So the steps above were very similar, starting an Ubuntu 24.10 VPS with 1GB ram, I only installed libpq-dev and rbenv as the dependencies.
TLDR; I think it would be nice to add to the wiki that creating a swapfile is necessary in addition to increasing tmpfs to 1G for low RAM machines, as the virtual ram is necessary for the builds to complete
First, without resizing /tmp/
apt update && apt upgrade
apt install libpq-dev
apt install rbenv
rbenv init
rbenv installed this version of rustc: rustc 1.80.1 (3f5fd8dd4 2024-08-06) (built from a source tarball)
rbenv install 3.3.0 --verbose
got stuck here
compiling builtin.c
So I would Ctr+C.
Using the --disable-yjit flag
Also stuck on builtin.c
Then after remount + resizing of tmpfs
Trying again after
mount -o remount,size=1G /tmp/
Build gets stuck on:
compiling bigdecimal.c
Checking usage of tmp after 20+ minutes
Filesystem Size Used Avail Use% Mounted on
tmpfs 1.0G 478M 547M 47% /tmp
I tried with a new version of rust (1.85.1) and this also got stuck. The build only completes when a swapfile is created.
using the --disable-yjit, also hangs on bigdecimal.c
Solution: Creating a swapfile
For every scenario above where the build failed when only installing libpq-dev, rbenv, the build failures/or build getting stuck were resolved by adding and enabling a swapfile.
sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=1024
sudo mkswap /mnt/swapfile
sudo swapon /mnt/swapfile
mount -o remount,size=1G /tmp/
The following scenarios I tested succeeded each time
- Installing rbenv which automatically installed
rustc 1.80.1Actually did work with that version of rustc! so that is not an issue. - Reinstalling a newer version of rustup, so that
rustc 1.85.1 (4eb161250 2025-03-15), also worked. - Using the
--disable-yjitflag succeeds as well
installing bundled gem cache: /root/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/cache
==> Installed ruby-3.3.0 to /root/.rbenv/versions/3.3.0
NOTE: to activate this Ruby version as the new default, run: rbenv global 3.3.0
Creating a swapfile and increasing tmpfs to 1G is necessary for the builds to complete. That would be useful to add to the docs, even though it's a workaround.