はじめてSinatraのDocker環境を作る
Sinatra+sqlite3+ActiveRecord

rubyからSinatra環境を作り 簡易ブログアプリ作成してみた!!

図1 実行結果

はじめに

軽量フレームワーク「Sinatra」の学習を始めたい。でも手軽に学習しようと思うと、便利なdocker環境の利用を考えますよね。でも良いなと思える「Sinatra」のimageが見付からなかったので、rubyのimage(下記のサイト)からコンテナを作成し、そこから欲しい環境を構築していこうと考えました。

使用したDocker image

bitnami/ruby:3.3のimageを使ったdocker-compose.ymlを作成し、このrubyコンテナに必要な環境を構築していきます。作成したコンテナは最後にimageに変換し、別の環境でも使えるようにしています。
今回の目標はSinatra+sqlite3+ActiveRecordが使える環境構築で、簡単な掲示板アプリを作って動作確認まで行いました。

docker-compose.yml の作成

imageが一つだけですので、docker-composeを使わなくても大丈夫ですけど、記録に残しつつ、今後の拡張性も考えてdocker-composeで進めることに。

docker-compose.yml

version: '3'

services:
  ruby:
    tty: true
    image: docker.io/bitnami/ruby:3.3
    ports:
      - 3020:3000
    volumes:
      - .:/app

コンテナを作成して起動

sudo docker-compose up -d      # ←起動
sudo docker ps                            # ←起動確認
 CONTAINER ID   IMAGE                          COMMAND                   CREATED          STATUS          PORTS                                                  NAMES
 b64ba14c7bc7   bitnami/ruby:3.3               "irb"                     49 seconds ago   Up 29 seconds   0.0.0.0:3020->3000/tcp, :::3020->3000/tcp              ruby-and-sinatra_ruby_1

インストールを始めます(環境作り)

まずはコンテナ内に入ります

 # 起動中のコンテナ内に入る
sudo docker exec -it ruby-and-sinatra_ruby_1 bash     
#  現状のバージョンを確認すると
gem -v (version: 3.5.10)
ruby -v (version: 3.3.1)
#  gem自身をアップグレードする場合は
gem update --system

その中でActiveRecord、sqlite3、Sinatraをインストールをしていきます。

gem install activerecord    (v7.1.3.3)

# irb (Interactive Ruby:rubyのinteractive modeでversion確認
irb(main):001> require "active_record"
=> true

irb(main):002> ActiveRecord.version
=> Gem::Version.new("7.1.3.3")
gem install sqlite3
......
1 gem installed

sqlite3 --version     (v3.40.1)
gem install sinatra     (v4.0.0)

gem install sinatra-contrib    (v4.0.0)

gem install rackup   (v3.0.11)

sqlite3のdbを作成するために、読み込む外部ファイル(seeds.sqlとします)を作成します。

seeds.sql

drop table if exists comments;
create table comments (
  id integer primary key,
  body text
);

insert into comments (body) values ('投稿 1');
insert into comments (body) values ('コメント 2');
insert into comments (body) values ('はじめに 3');

seeds.sqlを読み込ませる方法には2つあって、
1)コマンドラインで実行
2)sqlite3を実行してその中で読み込ませる

# 1) コマンドラインから直接読み込ませる方法
sqlite3 bbs.db <  seeds.sql 

# 2) sqlite3を実行してその中で読み込ませる方法
sqlite3  bbs.db
sqlite> .read seeds.sql

rubyでプログラミング

  • viewsフォルダを新しく作って、index.erb(個別ファイル)とlayout.erb(共通のファイル)を作る。
  • cssフォルダも新しく作って、styles.cssを作る。(今回はmain.jsは使わないです。)

ファイル構成

index.erb

<h1>My BBS (掲示板)</h1>
<ul>
  <% @comments.each do |item| %>
    <li>
        <%= item.body %>
    </li>
  <% end %>
</ul>

app.rb

require 'sinatra'
require 'sinatra/reloader'
require 'active_record'
require 'sqlite3'


ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: './bbs.db'
)

class Comment < ActiveRecord::Base
    validates :body , presence: true
    validates :body, length: {minimum: 12}
end


get '/' do
    @title = "My BBS"
    @comments = Comment.all
    erb :index
end

layout.erb

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title><%= @title %></title>
   <link rel="stylesheet" href="../css/styles.css">
</head>
<body>
  <div class="container">
    <%= yield %>
  </div>
</body>
</html>

styles.css

body {
    font-size: 16px;
    font-family: Verdana, sans-serif;
  }
  
  .container {
    width: 80%;
    max-width: 600px;
    margin: 20px auto;
  }
  
  h1 {
    font-size: 18px;
    border-bottom: 1px solid #ddd;
    padding-bottom: 10px;
  }
  
  ul > li {
    margin-bottom: 5px;
  }

  ul{
    list-style: square;
  }
  

最後にサーバーを起動して、ブラウザでlocalhost:3020を確認します。

ここで、docker-compose.yml を再度確認して、ローカルホスト側のポート番号とコンテナ内部で使用するポート番号を異なる値に設定している場合、サーバー起動時はコンテナ内部のポート番号を指定します。
ports:
- 3020:3000

ここでは上記のように指定しているので、3000ポートでサーバー起動して、ブラウザでは「localhost:3020」で確認する。(図1参照)

# サーバーを起動 
# -p ポートはコンテナ内部で使用するport番号です。
ruby app.rb -o 0.0.0.0 -p 3000

コンテナをimageにして再利用!!

最後にここまで作った環境をimageにする方法を参考までに載せておきます。コンテナ内でまだ何か作業を行っているなら終了させ、コンテナを停止させましょう。

その後(docker commitで)imageに変換します。docker-hubに登録されていない場合は、ひとまずファイルに保存(save)しておけば、他の環境に展開(load)できますので、ここではその方法を示します。

sudo docker-compose stop

# sudo docker  commit   <コンテナ名>   <image名>
# Image の名前は、慣習的に「ユーザ名/分かりやすい名前」なので、今回は「hiro/ruby3-sina」とします。
sudo docker commit  ruby3_ruby_1  hiro/ruby3-sina

# imageにできたか確認のため
sudo docker images
REPOSITORY                        TAG       IMAGE ID       CREATED         SIZE
hiro/ruby3-sina            latest    f62faea98d81   9 seconds ago   ***MB

 # ファイルにして保存(※保存するファイル名は、/を_にでも変更しておきましょう)
sudo docker save hiro/ruby3-sina > ./hiro_ruby3-sina.tar
# 念の為フル権限に
sudo chmod 777 ./hiro_ruby3-sina.tar

別環境(パソコン)で展開

#  imageをloadする
sudo docker load < ./hiro_ruby3-sina.tar
...展開中の表示...
Loaded image: hiro/ruby3-sina:latest

# image確認 
sudo docker images
REPOSITORY           TAG       IMAGE ID       CREATED       SIZE
hiro/ruby3-sina   latest    f62faea98d81   3 hours ago   ***MB

以上です😁

Follow me!