Skip to content

Commit c992f65

Browse files
authored
Merge pull request #2503 from pareenaverma/content_review
Ruby on Rails tech review
2 parents e8d2054 + 9e45199 commit c992f65

File tree

4 files changed

+183
-88
lines changed

4 files changed

+183
-88
lines changed

content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cascade:
77

88
minutes_to_complete: 40
99

10-
who_is_this_for: This learning path is intended for software developers deploying and optimizing Ruby on Rails workloads on Linux/Arm64 environments, specifically using Google Cloud C4A virtual machines powered by Axion processors.
10+
who_is_this_for: This is an introductory topic intended for software developers deploying and optimizing Ruby on Rails workloads on Linux Arm64 environments, specifically using Google Cloud C4A virtual machines powered by Axion processors.
1111

1212
learning_objectives:
1313
- Provision an Arm-based SUSE SLES virtual machine on Google Cloud (C4A with Axion processors)

content/learning-paths/servers-and-cloud-computing/ruby-on-rails/baseline.md

Lines changed: 139 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,157 @@ layout: learningpathall
77
---
88

99
## Baseline Setup for Ruby on Rails with PostgreSQL
10-
This section covers the installation and configuration of **PostgreSQL** and a **Rails application** on a SUSE Arm-based GCP VM. It includes setting up PostgreSQL, creating a Rails app, configuring the database, and starting the Rails server.
10+
This section sets up PostgreSQL and connects it with a Ruby on Rails application on a SUSE Arm64 Google Cloud C4A virtual machine. You’ll install PostgreSQL, configure it for Rails, create a database user, and verify that Rails can connect and serve requests successfully.
1111

1212
### Install and Configure PostgreSQL
13-
PostgreSQL is used with Ruby on Rails as a robust, production-ready relational database that reliably stores and manages application data.
13+
PostgreSQL is a robust, production-grade relational database that integrates seamlessly with Ruby on Rails.
14+
15+
Install PostgreSQL and its development headers:
1416

1517
```console
1618
sudo zypper install postgresql-devel postgresql-server
17-
sudo systemctl start postgresql
18-
sudo systemctl enable postgresql
1919
```
2020
- `postgresql-devel` is required to compile the pg gem for Rails.
2121

22-
Verify that the PostgreSQL service is active and running:
22+
After installation, ensure that PostgreSQL is running and configured to start automatically at boot:
2323

2424
```console
25+
sudo systemctl start postgresql
26+
sudo systemctl enable postgresql
2527
systemctl status postgresql
2628
```
29+
The output should look like:
30+
```output
31+
● postgresql.service - PostgreSQL database server
32+
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; vendor preset: disabled)
33+
Active: active (running) since Tue 2025-11-04 21:25:59 UTC; 18s ago
34+
Main PID: 26997 (postgres)
35+
Tasks: 7
36+
CPU: 372ms
37+
CGroup: /system.slice/postgresql.service
38+
├─ 26997 /usr/lib/postgresql15/bin/postgres -D /var/lib/pgsql/data
39+
├─ 26998 "postgres: logger " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
40+
├─ 26999 "postgres: checkpointer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
41+
├─ 27000 "postgres: background writer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" >
42+
├─ 27002 "postgres: walwriter " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
43+
├─ 27003 "postgres: autovacuum launcher " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
44+
└─ 27004 "postgres: logical replication launcher " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
45+
```
46+
If the Active state reads running, your PostgreSQL service is operational and ready for configuration.
2747

28-
This command creates a new PostgreSQL role (user) named `gcpuser` with **superuser privileges**.
48+
### Create a Database Role for Rails
49+
Next, create a dedicated PostgreSQL role (user) that Rails will use to connect to the database.
2950

3051
```console
31-
sudo -u postgres createuser --superuser gcpuser
52+
sudo -u postgres psql -c "CREATE USER gcpuser WITH SUPERUSER PASSWORD 'your_password';"
3253
```
33-
- `sudo -u postgres` → Runs the command as the `postgres` user (default PostgreSQL superuser).
34-
- `createuser --superuser gcpuser` → Creates a PostgreSQL role named `gcpuser` with full admin privileges.
35-
- Can create databases
36-
- Can create other roles/users
37-
- Can grant privileges
54+
This command:
55+
56+
Executes under the default PostgreSQL superuser account (postgres).
57+
Creates a new PostgreSQL role called gcpuser.
58+
Assigns superuser privileges, allowing the user to create databases, manage roles, and execute administrative tasks.
59+
60+
This user will serve as the Rails database owner and be referenced in the Rails configuration file (config/database.yml) later.
3861

39-
This role will be used by Rails to connect to the PostgreSQL database.
62+
### Set Environment variables
63+
64+
Before creating your Rails application, export environment variables so Rails and the `pg gem` can authenticate automatically with PostgreSQL.
65+
66+
```console
67+
export PGUSER=gcpuser
68+
export PGPASSWORD=your_password
69+
export PGHOST=localhost
70+
```
71+
72+
PGUSER → Specifies the PostgreSQL user that Rails will connect as.
73+
PGPASSWORD → Stores the password for that user in memory (temporary for this session).
74+
PGHOST → Points to the PostgreSQL host (in this case, the local VM).
4075

4176
### Create a Rails App with PostgreSQL
42-
Creates a new Rails application configured to use PostgreSQL as its database.
77+
Now, generate a new Rails application configured to use PostgreSQL as its default database adapter:
4378

4479
```console
4580
rails new db_test_rubyapp -d postgresql
4681
cd db_test_rubyapp
4782
bundle install
4883
```
49-
- Creates a new Rails application called `db_test_app`.
50-
- `d postgresql`Tells Rails to use PostgreSQL as the database instead of the default SQLite.
51-
- `bundle install` ensures all required gems are installed.
84+
- rails new db_test_rubyapp → Creates a new Rails application named db_test_rubyapp.
85+
- `d postgresql`Instructs Rails to use PostgreSQL instead of the default SQLite database.
86+
- bundle install → Installs all gem dependencies defined in the Gemfile, including the pg gem that connects Rails to PostgreSQL.
5287

5388
{{% notice Note %}}
5489
Check `config/database.yml` to ensure the `username` and `password` match your PostgreSQL role `(gcpuser)`.
5590
{{% /notice %}}
5691

5792
### Verify and Update Database Configuration
58-
Open the Rails database configuration file:
93+
Rails uses the `config/database.yml` file to define how it connects to databases in different environments (development, test, and production).
94+
It's important to verify that these credentials align with the PostgreSQL role you created earlier.
95+
96+
Open the file with your preferred text editor:
5997

6098
```console
61-
nano config/database.yml
99+
sudo vi config/database.yml
62100
```
63-
Find the `default`: and `development`: sections.
64-
Ensure the username matches the PostgreSQL user you created (gcpuser):
101+
Locate the default and development sections, and make sure they match the PostgreSQL user and password you configured.
65102

66-
You should see output similar to:
103+
Your configuration file should have the following fields set:
67104
```output
68105
default: &default
69106
adapter: postgresql
70107
encoding: unicode
71108
username: gcpuser
72-
password:
109+
password: your_password
73110
host: localhost
74111
pool: 5
75112
76113
development:
77114
<<: *default
78115
```
116+
117+
### Change the Authentication Method
118+
By default, PostgreSQL on many Linux distributions (including SUSE) uses the ident authentication method for local connections. This method maps Linux system usernames directly to PostgreSQL roles. While convenient for local access, it prevents password-based authentication, which is necessary for Rails and most application connections.
119+
120+
To allow Rails to connect using a username and password, change the authentication method in PostgreSQL’s configuration file `pg_hba.conf` from ident to md5.
121+
122+
Open your configuration file
123+
```console
124+
sudo vi /var/lib/pgsql/data/pg_hba.conf
125+
```
126+
The file location `/var/lib/pgsql/data/pg_hba.conf` is the default data directory path for PostgreSQL on SUSE Linux.
127+
128+
Find lines like the following in the file:
129+
130+
```output
131+
# IPv4 local connections:
132+
host all all 127.0.0.1/32 ident
133+
# IPv6 local connections:
134+
host all all ::1/128 ident
135+
```
136+
Modify both lines to use md5, which enables password-based authentication:
137+
138+
```output
139+
# IPv4 local connections:
140+
host all all 127.0.0.1/32 md5
141+
# IPv6 local connections:
142+
host all all ::1/128 md5
143+
```
144+
After saving the file, restart the PostgreSQL service to apply the new authentication settings:
145+
146+
```console
147+
sudo systemctl restart postgresql
148+
```
149+
150+
Verify the change:
151+
```console
152+
sudo systemctl status postgresql
153+
```
154+
The service should show as active (running).
155+
79156
### Create and Initialize the Database
80-
Initializes and creates the development and test databases for your Rails app using PostgreSQL.
157+
Once PostgreSQL is configured and Rails can authenticate, you can create your application’s development and test databases.
158+
This step verifies that Rails is correctly connected to PostgreSQL and that the pg gem is working on your Arm64 environment.
81159

160+
Run the following command from inside your Rails app directory:
82161
```console
83162
rails db:create
84163
```
@@ -87,22 +166,26 @@ You should see output similar to:
87166
Created database 'db_test_rubyapp_development'
88167
Created database 'db_test_rubyapp_test'
89168
```
90-
This means Rails successfully connected to PostgreSQL and created both dev and test databases.
169+
This output confirms that Rails successfully. It connected to the PostgreSQL service using the credentials from `config/database.yml` and created two new databases — one for development and one for testing.
91170

92171
### Generate a Scaffold for Testing
93-
A database and Scaffold are required to create the actual PostgreSQL database for your Rails app and quickly generate the model, controller, views, and migrations for your data.
94-
Let’s create a small test model and table — for example, a simple Task tracker:
172+
To verify your Ruby on Rails and PostgreSQL integration, you’ll create a small scaffold application.
173+
A scaffold is a Rails generator that automatically builds a model, controller, views, and database migration, allowing you to test CRUD (Create, Read, Update, Delete) operations quickly.
174+
175+
For this example, you’ll create a simple Task Tracker app that manages tasks with titles and due dates.
176+
Run the following command inside your Rails project directory:
95177

96178
```console
97179
rails generate scaffold task title:string due_date:date
98180
```
99-
This command automatically generates:
100-
- Database migration for the tasks table
101-
- A model (task.rb)
102-
- A controller and views for CRUD operations
103-
- **Scaffold** → Automatically generates boilerplate code for CRUD operations, saving time and ensuring your app has working forms and routes.
181+
This single command automatically generates:
182+
A database migration to create the tasks table in PostgreSQL.
183+
A model file (app/models/task.rb) that maps to the tasks table.
184+
A controller (app/controllers/tasks_controller.rb) with full CRUD actions (index, show, new, create, edit, update, destroy).
185+
Corresponding views in app/views/tasks/ with ready-to-use HTML + embedded Ruby templates.
186+
Route entries in config/routes.rb to make the new resource accessible via /tasks.
104187

105-
Then apply the migration:
188+
Now apply the migration to create the tasks table in your PostgreSQL database:
106189

107190
```console
108191
rails db:migrate
@@ -116,22 +199,27 @@ You should see output similar to:
116199
== 20251006101717 CreateTasks: migrated (0.0128s) =============================
117200
```
118201

119-
Database schema successfully updated.
202+
This confirms that Rails connected successfully to PostgreSQL and the database schema was updated.
203+
The new tasks table was created inside your db_test_rubyapp_development database.
120204

121205
### Verify Table and Database Connectivity
122-
The previous command `rails generate scaffold task title:string due_date:date` created a `tasks` table in your PostgreSQL database.
123-
124-
Now, verify that the table exists and has the correct structure following the steps below:
206+
TThe scaffold created a tasks table in your PostgreSQL database. Verify it exists and has the expected schema:
125207

126208
```console
127209
sudo -u postgres psql
210+
```
211+
Inside the PostgreSQL shell, run:
212+
213+
```console
128214
\c db_test_rubyapp_development
129215
\d tasks
216+
\q
130217
```
131218
- `sudo -u postgres psql` → Launches the PostgreSQL shell as the superuser `postgres`.
132219
- `\c db_test_rubyapp_development` → Connects to the Rails app’s development database.
133220
- `\d tasks` → Displays the schema (columns and types) of the `tasks` table.
134-
221+
- `\q → Exit from the PostgreSQL shell
222+
135223
You should see output similar to:
136224
```output
137225
psql (15.10)
@@ -152,7 +240,7 @@ Indexes:
152240
"tasks_pkey" PRIMARY KEY, btree (id)
153241
```
154242

155-
### Run Rails Server
243+
### Open port 3000 in Google Cloud (VPC firewall)
156244
Before proceeding to run the Rails server, you need to allow port 3000 from your GCP console. Below are the steps to do that:
157245

158246
a. On the GCP console, navigate to **Firewall** -> **Create Firewall Rule**
@@ -182,13 +270,22 @@ In the **"Protocols and Ports"**, click on **"TCP"**, and mention the port numbe
182270
Click on **"Create"**. The Firewall rule will be created successfully and can be viewed in the Firewall Policies Page:
183271

184272
![ Create Firewall rule alt-text#center](images/firewall5.png "Figure 5: Create Firewall rule")
185-
186-
Once done, go back to the VM, and execute the below commands to allow port 3000:
273+
274+
### OS firewall (firewalld) on SUSE
275+
Once done, go back to your VM, install FirewallD:
276+
```console
277+
sudo zypper install firewalld
278+
```
279+
Now start FirewallD and execute the commands to allow port 3000:
187280

188281
```console
282+
sudo systemctl start firewalld
283+
sudo systemctl enable firewalld
189284
sudo firewall-cmd --permanent --add-port=3000/tcp
190285
sudo firewall-cmd --reload
191286
```
287+
288+
## Start Rails
192289
Now that port 3000 is allowed in your VM’s ingress firewall rules, you can start the Rails server using the following command:
193290

194291
```console
@@ -210,4 +307,4 @@ You will see a Rails welcome page in your browser if everything is set up correc
210307

211308
![Rails-info page alt-text#center](images/rails-web.png "Figure 6: Ruby/Rails Welcome Page")
212309

213-
This verifies the basic functionality of the Ruby/Rails installation before proceeding to the benchmarking.
310+
With port 3000 reachable and the welcome page loading, your Rails stack on SUSE Arm64 (C4A Axion) is verified end-to-end and you can proceed to benchmarking.

content/learning-paths/servers-and-cloud-computing/ruby-on-rails/benchmarking.md

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ layout: learningpathall
77
---
88

99

10-
## Ruby on Rails Benchmarking with built-in Benchmark
11-
This section benchmarks Ruby on Rails using Ruby’s built-in `Benchmark` library to measure execution time for database inserts, queries, and CPU computations on GCP SUSE VMs, providing insights into performance metrics and bottlenecks.
10+
## Ruby on Rails Benchmarking
11+
In this section you will benchmark Ruby on Rails using Ruby’s built-in `Benchmark` library to measure execution time for database inserts, queries, and CPU computations on GCP SUSE VMs, providing insights into performance metrics and bottlenecks.
1212

1313
### Go into your Rails app folder
14-
You need to navigate into the folder of your Rails application. This is where Rails expects your application code, models, and database configurations to be located. All commands related to your app should be run from this folder.
14+
Navigate into the folder of your Rails application. This is where Rails expects your application code, models, and database configurations to be located. All commands related to your app should be run from this folder.
1515

1616
```console
1717
cd ~/db_test_rubyapp
1818
````
1919

20-
### Create the benchmark file inside the app
21-
We create a new Ruby file named `benchmark.rb` where we will write code to measure performance.
20+
### Create the benchmark
21+
Now create a new Ruby file named `benchmark.rb` where you will write code to measure performance.
2222

2323
```console
24-
nano benchmark.rb
24+
vi benchmark.rb
2525
```
2626

2727
### Benchmark code for measuring Rails app performance
28-
Below mentioned code (`benchmark.rb` file) measures database inserts, queries, and CPU computations in your Rails application using Ruby’s Benchmark library.
28+
Copy the code below into `benchmark.rb`. It measures database inserts, queries, and CPU computations in your Rails application using Ruby’s Benchmark library.
2929

3030
```ruby
3131
require 'benchmark'
@@ -62,21 +62,21 @@ end
6262
This code gives you a basic understanding of how your Rails app performs under different types of workloads.
6363

6464
### Run the benchmark inside Rails
65-
Now that your benchmark file is ready, run it **within the Rails environment** using the following command:
65+
Now that your benchmark file is ready, run it within the Rails environment using the following command:
6666

6767
```console
6868
rails runner benchmark.rb
6969
```
70-
- `rails runner` runs any Ruby script in the context of your Rails application.
70+
`rails runner` runs any Ruby script in the context of your Rails application.
7171

72-
- It automatically loads your **Rails environment**, including:
72+
It automatically loads your Rails environment, including:
7373
- All models (like `Task`)
7474
- Database connections
7575
- Configuration and dependencies
7676

77-
- This ensures that your benchmark can interact with the **PostgreSQL database** through ActiveRecord, rather than running as a plain Ruby script.
77+
This ensures that your benchmark can interact with the PostgreSQL database through ActiveRecord, rather than running as a plain Ruby script.
7878

79-
You should see an output similar to:
79+
You should see output similar to:
8080

8181
```output
8282
user system total real
@@ -92,17 +92,8 @@ Computation: 0.410907 0.000000 0.410907 ( 0.410919)
9292
- **total**`user + system` (sum of CPU processing time).
9393
- **real** → The **wall-clock time** (actual elapsed time, includes waiting for DB, I/O, etc).
9494

95-
### Benchmark summary on x86_64
96-
To compare the benchmark results, the following results were collected by running the same benchmark on a `x86 - c4-standard-4` (4 vCPUs, 15 GB Memory) x86_64 VM in GCP, running SUSE:
97-
98-
| Task | user (sec) | system (sec) | total (sec) | real (sec) |
99-
|--------------|------------|--------------|-------------|------------|
100-
| DB Insert | 1.902564 | 0.061805 | 1.964369 | 2.606764 |
101-
| DB Query | 2.725923 | 0.009513 | 2.735436 | 2.735956 |
102-
| Computation | 0.331519 | 0.000083 | 0.331602 | 0.331610 |
103-
10495
### Benchmark summary on Arm64
105-
Results from the earlier run on the `c4a-standard-4` (4 vCPU, 16 GB memory) Arm64 VM in GCP (SUSE):
96+
Results summarized from the your run on the `c4a-standard-4` (4 vCPU, 16 GB memory) Arm64 VM in GCP (SUSE):
10697

10798

10899
| Task | user (sec) | system (sec) | total (sec) | real (sec) |
@@ -112,10 +103,12 @@ Results from the earlier run on the `c4a-standard-4` (4 vCPU, 16 GB memory) Arm6
112103
| Computation | 0.410907 | 0.000000 | 0.410907 | 0.410919 |
113104

114105

115-
### Ruby/Rails performance benchmarking comparison on Arm64 and x86_64
106+
### Key Takeaways
107+
108+
When you look the benchmarking results, you will notice that on the Google Axion C4A Arm-based instances:
116109

117-
When you compare the benchmarking results, you will notice that on the Google Axion C4A Arm-based instances:
110+
Rails on Arm64 performs consistently: Ruby and PostgreSQL are both natively optimized for Arm, providing stable, predictable latency.
111+
Database I/O remains the main optimization target: Techniques such as query caching, connection pooling, and async queries can improve DB-heavy performance.
112+
Compute-bound tasks scale well: Axion’s Arm cores and Ruby’s YJIT show excellent CPU utilization for non-I/O workloads.
118113

119-
- **Database operations are the main bottleneck:** DB Insert and DB Query take the most time.
120-
- **DB Query has the highest latency:** It is the slowest operation at 3.39 seconds.
121-
- **Core computation is fast:** Pure Ruby/Rails calculations complete quickly at 0.41 seconds.
114+
Ruby on Rails runs efficiently on Google Cloud’s Axion-based C4A Arm64 instances.

0 commit comments

Comments
 (0)