2025년 10월 3일 금요일

루비 온 레일즈 설치 및 개발 방법 요약 정리

이 글은 루비 온 레일즈 설치 및 개발 방법을 요약 정리한 글이다. 


1. 개요
루비온레일즈(Ruby on Rails)는 루비(Ruby) 프로그래밍 언어로 작성된 서버 측 웹 애플리케이션 프레임워크이다. 일반적으로 '레일즈(Rails)'로 줄여 부르며, 2004년 데이비드 하이네마이어 한손(David Heinemeier Hansson)에 의해 처음 공개되었다. 레일즈의 핵심 개발 철학은 '설정보다 관례(Convention over Configuration, CoC)'와 '반복하지 마라(Don't Repeat Yourself, DRY)'이며, 이는 개발자가 반복적인 설정 작업에서 벗어나 비즈니스 로직에 집중하게 함으로써 웹 개발의 생산성을 획기적으로 향상시키는 것을 목표로 한다.

2. 배경 및 핵심 개념
레일즈는 MVC(Model-View-Controller) 아키텍처 패턴을 근간으로 설계되었다. 이는 애플리케이션의 구성 요소를 세 가지 역할로 명확히 분리하여 코드의 구조를 체계적으로 관리하는 방식이다.
  • 모델 (Model): 애플리케이션의 데이터와 비즈니스 로직을 담당한다. 데이터베이스 테이블에 직접 대응되며, 데이터의 유효성 검사, 처리, 저장 등의 역할을 수행한다.
  • 뷰 (View): 사용자에게 보여지는 UI(사용자 인터페이스)를 생성하는 역할을 한다. HTML, CSS, JavaScript 코드를 동적으로 생성하여 웹 브라우저에 표시할 최종 결과물을 만든다.
  • 컨트롤러 (Controller): 모델과 뷰 사이의 중재자 역할을 한다. 사용자의 요청(HTTP Request)을 받아 분석하고, 필요한 모델을 호출하여 데이터를 처리한 뒤, 그 결과를 다시 뷰에 전달하여 사용자에게 응답(HTTP Response)을 보낸다.
이러한 구조 덕분에 개발자는 데이터, 로직, 화면 표시 코드를 분리하여 유지보수가 용이하고 확장성 높은 애플리케이션을 구축할 수 있다.

3. 장점 및 단점

장점

  • 높은 생산성과 개발 속도: CoC 철학과 스캐폴딩(scaffolding) 같은 강력한 코드 자동 생성 기능은 CRUD(생성, 읽기, 갱신, 삭제) 기반의 기능을 매우 빠르게 구현하게 해준다.

  • 거대하고 활발한 생태계: '젬(Gem)'이라고 불리는 수많은 오픈소스 라이브러리가 존재하여 인증, 결제, 파일 업로드 등 다양한 기능을 몇 줄의 코드로 손쉽게 추가할 수 있다.

  • 가독성 및 유지보수성: 루비 언어 자체의 간결하고 우아한 문법과 레일즈의 잘 정립된 관례는 코드의 가독성을 높여 팀 단위 협업과 장기적인 유지보수를 용이하게 한다.

단점

  • 상대적으로 느린 실행 속도: 인터프리터 언어인 루비의 특성상, Go나 Java와 같은 컴파일 언어 기반의 프레임워크에 비해 요청 처리 속도가 느릴 수 있다.

  • 초기 학습 곡선: 레일즈의 많은 부분이 '마법'처럼 자동으로 동작하기 때문에, 내부 동작 원리를 깊이 이해하기 전까지는 문제 발생 시 원인을 파악하고 디버깅하는 데 어려움을 겪을 수 있다.

  • 제한적인 유연성: 레일즈가 제시하는 강력한 관례는 대부분의 웹 애플리케이션 개발에 최적화되어 있지만, 매우 특수하거나 비표준적인 구조를 가진 시스템을 개발할 때는 오히려 제약이 될 수 있다.


젬은 현재 인공지능 기술 스텍을 고려해 발전 중이다. 루비(Ruby) 생태계의 중심에는 루비젬스(RubyGems)라는 강력한 패키지 관리 시스템이 자리 잡고 있다. 이는 전 세계의 루비 개발자들이 만든 수많은 라이브러리를 젬(Gem)'이라는 표준화된 패키지 형태로 공유하고 재사용할 수 있도록 하는 핵심적인 기반이다. 개발자는 젬을 통해 인증, 데이터베이스 연동, 웹 서버 구동과 같은 복잡한 기능을 직접 구현할 필요 없이, 이미 검증된 코드를 자신의 프로젝트에 손쉽게 통합하여 개발 생산성을 극대화할 수 있다. 이러한 의존성을 체계적으로 관리하는 도구가 바로 번들러(Bundler)이다. 프로젝트의 Gemfile에 필요한 젬의 이름과 버전을 명시하면, 번들러는 해당 젬뿐만 아니라 그 젬이 의존하는 다른 모든 젬까지 정확한 버전으로 설치하여 개발 환경의 일관성을 보장한다.

이는 여러 개발자가 협업하는 환경에서 발생할 수 있는 잠재적인 충돌을 방지하고 안정적인 애플리케이션 운영을 가능하게 하는 필수적인 과정이다. 최근 인공지능, 특히 거대 언어 모델(LLM)이 기술의 새로운 패러다임으로 부상하면서 루비 커뮤니티 역시 이러한 변화에 발 빠르게 대응하고 있다. 루비의 강점인 뛰어난 가독성과 개발 편의성을 바탕으로, 복잡한 AI 기능을 애플리케이션에 통합하기 위한 다양한 젬들이 활발하게 개발되는 중이다. 가장 대표적인 것은 ruby-openai 젬으로, OpenAI가 제공하는 GPT, DALL-E와 같은 강력한 모델들의 API를 루비 코드 내에서 직관적으로 호출할 수 있게 해준다. 이를 통해 개발자는 손쉽게 챗봇, 콘텐츠 생성, 이미지 생성과 같은 최신 AI 기능을 자신의 서비스에 접목할 수 있다. 여기서 한 걸음 더 나아가, langchainrb는 LLM을 활용한 고수준의 애플리케이션을 구축하기 위한 프레임워크를 제공한다. 이는 단순히 API를 한 번 호출하는 것을 넘어, 여러 단계의 프롬프트를 연결하는 '체인'이나 LLM이 특정 도구를 사용하도록 만드는 '에이전트'와 같은 복잡한 로직을 구조적으로 설계할 수 있도록 돕는다.


4. 우분투 22.04 환경 설치 방법
우분투 22.04 환경에서 루비온레일즈 개발 환경을 구축하는 가장 안정적인 절차는 다음과 같다. 여러 버전의 루비를 관리하기 용이한 rbenv를 사용하는 방식이다.


1단계: 시스템 업데이트 및 필수 패키지 설치

먼저 패키지 목록을 최신화하고, 루비 소스 코드를 컴파일하고 레일즈를 실행하는 데 필요한 기본적인 도구들을 설치한다.

sudo apt update
sudo apt install -y git curl build-essential libssl-dev libreadline-dev zlib1g-dev

2단계: rbenv를 이용한 루비 설치

rbenv는 시스템에 여러 버전의 루비를 독립적으로 설치하고 프로젝트별로 다른 버전을 사용하도록 전환해주는 버전 관리 도구이다.

# rbenv와 ruby-build(rbenv의 플러그인) 설치
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

# 터미널이 rbenv 명령어를 인식하도록 환경 변수 설정
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc

# 변경된 셸 설정 적용 (터미널 재시작 또는 아래 명령어 실행)
exec $SHELL

# 원하는 루비 버전 설치 (예: 3.2.2 버전)
rbenv install 3.2.2

# 시스템 전역에서 사용할 기본 루비 버전으로 지정
rbenv global 3.2.2

# 루비 설치 확인
ruby -v

3단계: 레일즈(Rails) 설치

루비의 패키지 매니저인 gem을 사용하여 레일즈를 설치한다.

# 최신 버전의 레일즈 설치 (예: 7.1.3 버전)
gem install rails -v 7.1.3

# rbenv가 새로 설치된 레일즈 명령어를 인식하도록 갱신
rbenv rehash

# 레일즈 설치 확인
rails -v

4단계: 데이터베이스(PostgreSQL) 설치

레일즈는 SQLite, MySQL, PostgreSQL 등 다양한 데이터베이스를 지원하지만, 실제 서비스 환경에서는 PostgreSQL이 널리 사용된다.

# PostgreSQL 및 관련 개발 라이브러리 설치
sudo apt install -y postgresql postgresql-contrib libpq-dev

# 현재 로그인한 사용자를 데이터베이스 슈퍼유저로 생성
sudo -u postgres createuser -s $USER

# 현재 사용자 이름으로 기본 데이터베이스 생성
createdb $USER

5. 예제 프로젝트 생성 및 실행

1단계: 신규 레일즈 프로젝트 생성

rails new 명령어를 사용하여 blog라는 이름의 프로젝트를 생성한다. -d postgresql 옵션은 PostgreSQL을 기본 데이터베이스로 사용하겠다고 명시하는 것이다.

rails new blog -d postgresql

2단계: 데이터베이스 설정 및 생성

프로젝트 폴더로 이동한 후, 레일즈 명령어를 통해 config/database.yml 파일의 설정에 맞춰 개발용 및 테스트용 데이터베이스를 생성한다.

cd blog
rails db:create

3단계: 스캐폴드(Scaffold)를 이용한 기능 자동 생성

스캐폴드는 모델, 뷰, 컨트롤러, 라우팅, 데이터베이스 스키마 변경 파일(마이그레이션) 등 특정 리소스에 대한 CRUD 기능의 기본 뼈대를 한 번에 생성해주는 강력한 도구이다. Post라는 리소스를 title(문자열)과 body(텍스트) 속성을 갖도록 생성한다.

rails generate scaffold Post title:string body:text

4단계: 데이터베이스 마이그레이션

위에서 생성된 마이그레이션 파일을 실행하여 실제 데이터베이스에 posts 테이블을 생성한다.

rails db:migrate

5단계: 개발 서버 실행

레일즈에 내장된 puma 웹 서버를 실행한다.

rails server

서버가 정상적으로 실행되면, 웹 브라우저에서 http://localhost:3000/posts 주소로 접속하여 게시물을 생성, 조회, 수정, 삭제할 수 있는 간단한 블로그 애플리케이션을 확인할 수 있다.

6. 프로젝트 폴더 구조 및 주요 코드 설명

레일즈 프로젝트는 관례에 따라 명확한 폴더 구조를 가진다.

  • app/: 애플리케이션의 핵심 코드가 위치하는 가장 중요한 디렉터리이다.

models/post.rb: Post 모델 클래스 파일이다. 데이터베이스 posts 테이블과의 연결, 데이터 유효성 검사 등을 정의한다.

controllers/posts_controller.rb: posts 리소스와 관련된 요청을 처리하는 컨트롤러이다. index, show, new, create 등의 액션 메서드를 포함한다.

views/posts/: posts와 관련된 뷰 파일들이 모여 있는 폴더이다. index.html.erb, show.html.erb 등이 있다.

  • config/: 애플리케이션의 설정을 관리하는 파일들이 위치한다.

routes.rb: URL과 컨트롤러 액션을 연결하는 라우팅 규칙을 정의하는 파일이다.

database.yml: 데이터베이스 연결 정보를 환경별(개발, 테스트, 운영)로 설정하는 파일이다.

  • db/: 데이터베이스 관련 파일들이 위치한다.

migrate/: 데이터베이스 스키마의 변경 이력을 관리하는 마이그레이션 파일들이 순서대로 저장된다.

  • Gemfile: 프로젝트가 의존하는 외부 라이브러리(Gem) 목록을 관리하는 파일이다.


주요 코드 예시

config/routes.rb (라우팅)

rails generate scaffold Post 명령어를 실행하면 이 파일에 resources :posts 한 줄이 자동으로 추가된다. 이는 Post 리소스에 대한 7가지 기본 RESTful 경로(index, show, new, edit, create, update, destroy)를 자동으로 생성한다.

Rails.application.routes.draw do
  resources :posts
end

app/controllers/posts_controller.rb (컨트롤러)

index 액션은 모든 게시물(Post.all)을 데이터베이스에서 조회하여 @posts라는 인스턴스 변수에 담아 index.html.erb 뷰 파일로 전달하는 역할을 한다.

class PostsController < ApplicationController
  # GET /posts
  def index
    @posts = Post.all
  end
  # ... (show, new, create 등의 다른 액션들)
end

app/views/posts/index.html.erb (뷰)

HTML 코드 안에 <% ... %> 또는 <%= ... %> 형태로 루비 코드를 삽입할 수 있는 ERB(Embedded Ruby) 템플릿 파일이다. 컨트롤러에서 전달받은 @posts 배열을 순회하며 각 게시물의 내용을 화면에 출력한다.

<h1>Posts</h1>

<% @posts.each do |post| %>
  <div id="<%= dom_id post %>">
    <p>
      <strong>Title:</strong>
      <%= post.title %>
    </p>
    <p>
      <strong>Body:</strong>
      <%= post.body %>
    </p>
  </div>
<% end %>


부록: 스마트빌딩 KPI 데쉬보드 개발 예시


1. 프로젝트 개요

본 문서는 루비온레일즈(Ruby on Rails)로 구축된 스마트 빌딩 KPI 대시보드 애플리케이션에 대한 기술 분석 문서이다. 이 애플리케이션은 다크모드 UI와 동적 차트를 통해 건물의 핵심 성과 지표(KPI) 데이터를 효과적으로 시각화하는 것을 목적으로 한다.

이 프로젝트 전체 코드는 다음 링크에서 다운로드 받을 수 있다.



2. 프로젝트 구조

프로젝트는 루비온레일즈의 표준적인 디렉터리 구조를 따른다.

└── blog/
    ├── app/
    │   ├── controllers/
    │   │   └── dashboard_controller.rb
    │   ├── models/
    │   ├── views/
    │   │   ├── layouts/
    │   │   │   └── dashboard.html.erb
    │   │   └── dashboard/
    │   │       └── index.html.erb
    │   ├── assets/
    │   │   └── stylesheets/
    │   │       └── dashboard.css
    ├── config/
    │   ├── routes.rb
    │   ├── puma.rb
    │   └── database.yml
    └── Gemfile


3. MVC 아키텍처 및 동작 메커니즘

애플리케이션은 MVC(Model-View-Controller) 패턴을 기반으로 동작한다.

요청 처리 흐름

  1. 브라우저 요청: 사용자가 http://localhost:3001/ 주소로 접속한다.

  2. 라우팅: config/routes.rb 파일이 요청 URL을 분석하여 dashboard 컨트롤러의 index 액션에 연결한다.

  3. 컨트롤러: dashboard_controller.rb의 index 액션이 실행된다. 여기서 비즈니스 로직을 처리하고 뷰에 전달할 데이터를 준비한다.

  4. 뷰 렌더링: 컨트롤러는 dashboard/index.html.erb 뷰 파일을 렌더링하여 동적인 HTML을 생성한다.

  5. 레이아웃 적용: 생성된 HTML은 공통 구조를 정의하는 layouts/dashboard.html.erb 레이아웃에 삽입된다.

  6. 응답: 최종적으로 완성된 HTML 페이지가 사용자의 브라우저로 전송된다.


주요 구성 요소

  • 라우팅 (config/routes.rb): URL과 컨트롤러 액션을 매핑하는 규칙을 정의한다.
    Ruby
    Rails.application.routes.draw do
      root "dashboard#index"
      get 'dashboard', to: 'dashboard#index'
    end

    루트 경로(/)를 dashboard 컨트롤러의 index 액션으로 지정한다.

  • 컨트롤러 (app/controllers/dashboard_controller.rb): 비즈니스 로직을 처리하고 뷰에 전달할 데이터를 준비하는 역할을 담당한다.
    Ruby
    class DashboardController < ApplicationController
      layout 'dashboard'

      def index
        @energy_consumption = { today: 2847.5 }
        @occupancy = { current: 142 }
        @temperature = { current: 22.5 }
      end
    end

    @ 기호로 시작하는 인스턴스 변수를 사용하여 뷰에 데이터를 전달하며, layout 'dashboard' 코드를 통해 이 컨트롤러의 모든 액션이 dashboard.html.erb 레이아웃을 사용하도록 명시한다.

  • 뷰 (app/views/dashboard/index.html.erb): 컨트롤러로부터 전달받은 데이터를 기반으로 사용자에게 보여질 HTML 구조를 정의한다. KPI 카드와 차트 영역으로 구성된다.

  • 레이아웃 (app/views/layouts/dashboard.html.erb): 애플리케이션 내 여러 뷰에서 공통으로 사용되는 HTML 뼈대를 제공한다. 외부 CSS, JavaScript 라이브러리 링크와 같은 공통 요소를 포함한다.


4. 대시보드 주요 기능

KPI 지표
  • 에너지 소비량: 실시간 전력 사용량 및 전일 대비 변화율을 표시한다.

  • 점유율: 현재 재실 인원 및 층별 분포 현황을 보여준다.

  • 온도: 층별 실내 온도를 모니터링하고 상태를 표시한다.

  • 공기질: AQI, CO2, 습도, PM2.5 등 실내 공기질 데이터를 제공한다.


시각화 차트

  • 월별 에너지 소비 차트: Chart.js 라이브러리를 사용한 막대 차트로 월별 에너지 사용량을 시각화한다.

  • 층별 점유율 차트: 도넛 차트를 통해 층별 재실 인원 분포를 직관적으로 보여준다.

  • 시간별 점유율 추이: 꺾은선 그래프로 시간의 흐름에 따른 점유율 변화를 나타낸다.


5. 기술 스택

백엔드
  • 웹 프레임워크: Ruby on Rails 7.1.5

  • 웹 서버: Puma (포트 3001에서 실행되도록 설정됨)

  • 데이터베이스: PostgreSQL (설정은 되어 있으나 예제에서는 직접 사용하지 않음)


프론트엔드

  • 템플릿 엔진: ERB (Embedded Ruby)

  • 차트 라이브러리: Chart.js

  • 아이콘: Font Awesome

  • 폰트: Google Fonts (Inter)

  • 스타일링: 다크 테마를 위한 Custom CSS


6. 서버 설정 및 실행

Puma 웹 서버 설정 (config/puma.rb)

Puma 웹 서버의 포트, 스레드, PID 파일 위치 등을 설정하는 파일이다.


port ENV.fetch("PORT") { 3001 }
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
pidfile "tmp/pids/server.pid"


실행 명령어

터미널에서 아래 명령어를 통해 개발 서버를 시작할 수 있다.

rails server

위 명령어는 config/puma.rb 설정에 따라 3001번 포트에서 서버를 실행한다.


7. 데이터 흐름

  1. 컨트롤러에서 데이터 준비: 컨트롤러의 index 액션에서 KPI 데이터를 해시(Hash) 형태로 생성하여 인스턴스 변수에 할당한다.
    Ruby
    @energy_consumption = {
      today: 2847.5,
      weekly_data: [2800, 3100, 2950]
    }

  2. 뷰에서 데이터 표시: ERB 문법을 사용하여 HTML 태그 내에 컨트롤러에서 전달된 데이터를 출력한다.
    코드 스니펫
    <span class="value"><%= @energy_consumption[:today] %></span>

  3. JavaScript에서 차트 데이터로 활용: to_json 메서드로 루비 객체를 JSON 문자열로 변환한 후, JavaScript 코드에서 차트 데이터로 사용한다.
    JavaScript
    const weeklyData = <%= @energy_consumption[:weekly_data].to_json.html_safe %>;


8. 향후 확장 방안

  • 실시간 데이터 연동: WebSocket 또는 Server-Sent Events를 활용하여 외부 IoT 센서 API와 연동하고, Redis를 통해 데이터를 캐싱하여 실시간성을 확보할 수 있다.

  • 데이터베이스 연동: PostgreSQL에 KPI 데이터를 저장할 모델을 생성하고, 과거 데이터 조회 및 통계 분석 기능을 구현할 수 있다.

  • 사용자 인증: Devise와 같은 인증 Gem을 활용하여 로그인 시스템을 구축하고 사용자 권한별로 접근 제어를 구현할 수 있다.

  • API 개발: 모바일 앱이나 외부 시스템과 연동하기 위한 JSON API 엔드포인트를 추가할 수 있다.