Recently, I was following a guide to set up Ruby on Rails on an Amazon EC2 instance using the “Basic 32-bit Amazon Linux AMI 2010.11.1 Beta”, and I hit a wall. Things were smooth until I reached step 3.3, which asks you to run:
bundle install
This is where the trouble began. The terminal threw the following error:
Error Code
Installing sqlite3 (1.3.3) with native extensions
/usr/lib/ruby/site_ruby/1.8/rubygems/installer.rb:529:in `build_extensions':
ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)
/usr/bin/ruby extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h
At first, I thought I’d missed a step. Turns out, I was right but the issue was deeper than just a skipped line.
Define the Error
Let me explain what I found out.
Missing Ruby Development Headers
The key part of the error was:
mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h
This means the Ruby development headers (ruby-devel
) weren’t installed. These headers are necessary when a gem (like sqlite3
) needs to compile native C extensions on your machine.
So, even though Ruby itself was installed, it wasn’t enough.
Missing SQLite3 Headers
After installing ruby-devel
, I ran bundle install
again… and boom! Another error:
checking for sqlite3.h... no
sqlite3.h is missing. Try 'yum install sqlite3-devel'
This told me that the SQLite development files (sqlite-devel
) were also missing which are again required for compiling the sqlite3
gem.
How I Fix It
Even though yum
told me that some packages were already installed, I reinstalled everything properly just to be sure. Here’s exactly what I did:
Correct Code
# Update your EC2 instance
sudo yum update -y
# Install Ruby development headers
sudo yum install ruby-devel -y
# Install SQLite3 development headers
sudo yum install sqlite-devel -y
# Install essential build tools
sudo yum install gcc make -y
Then I tried again:
bundle install
And finally, it worked! The sqlite3 gem compiled without errors.
Practice Functionality Testing My Setup
To make sure everything was running correctly and to give myself a bit of hands-on practice I created a simple Rails project that uses SQLite3 as the database.
Install Rails
gem install rails
Create a New Rails App
new testapp -d sqlite3
cd testapp
bundle install
Generate a Model
generate model Post title:string content:text
rake db:migrate
Open Rails Console
rails console
And I ran this code to verify database interaction:
Post.create(title: "First Post", content: "Rails is working!")
puts Post.all.inspect
Success! My first Rails object was stored and retrieved properly.
Extra Debug Tip Manually Finding Header File
If you’re still getting missing file errors like sqlite3.h
, try this:
find / -name sqlite3.h 2>/dev/null
If it’s there but not being found, you can force the compiler to look in the right place:
export CFLAGS=-I/usr/include
export LDFLAGS=-L/usr/lib
bundle install
Sometimes, paths aren’t configured correctly on older AMIs, so these environment variables help point the compiler in the right direction.
Summary Table
Here’s a quick reference I wish I had when I started:
Component | Required Package | Command |
---|---|---|
Ruby Headers | ruby-devel | sudo yum install ruby-devel |
SQLite Headers | sqlite-devel | sudo yum install sqlite-devel |
Build Tools | gcc , make | sudo yum install gcc make |
Final Thoughts
This entire experience was a reminder: setting up Ruby on Rails in a cloud environment like EC2 isn’t always plug-and-play especially when dealing with native gems like sqlite3
.
I learned the hard way that:
ruby-devel
is a must for native gem compilationsqlite-devel
is needed even if you think SQLite is already installed- Build tools like
gcc
andmake
are often forgotten but critical
If you’re still setting things up, I’d suggest exploring alternatives like PostgreSQL or MySQL for production environments. You can also practice switching databases inside Rails apps to understand how gem
dependencies shift.