Dev Containerで作る Sinatra 開発環境(MySQL対応)
はじめに
Dev Containerは、Dockerコンテナ上で開発環境を管理できる仕組みです。
VS CodeのDev Containersを使えば、簡単にセットアップできます。
通常、ローカル環境で開発する際には、ホストOSに必要なGemやライブラリをインストールして環境を構築します。
通常の開発
一方で、Dev Containerを使用した場合の構成は次のようになります。
DevContainerを用いた開発
Dev Containerを使用するメリット
-
Rubyのバージョンをプロジェクトごとに管理
システムに影響を与えず、プロジェクトごとに必要なRubyのバージョンを切り替えられます。 -
VS Codeの設定や拡張機能を分離
必要な設定や拡張機能をコンテナ内にまとめ、他のプロジェクトやローカル環境への影響を防ぎます。
これらの仕組みにより、開発環境の再現性が高まり、効率的かつ柔軟な開発が可能になります。
この記事では、Dev Containerを使って以下の環境を構築する手順を解説します。
- Sinatra・MySQL開発環境
- コード整形・品質チェック(Prettier、Rubocop、RubyLSP)環境
環境構築手順
準備
- VS Codeをインストール
- Dev Containersをインストール
- Dockerをインストール
Ruby環境構築
- Dev Containerで作るRuby開発環境(Prettier & Rubocop & RubyLSP対応)を参考に、必要な設定を行います。
- Dev Containerを起動
Sinatraのセットアップ
-
Gemfileに追記
Gemfile... gem 'sinatra'
-
依存関係をインストール
bundle install
-
index.rbを新規作成
index.rb# frozen_string_literal: true require 'sinatra' get '/' do 'Hello, world!' end
-
アプリケーションを実行
bundle exec ruby index.rb
-
動作確認
ブラウザでhttp://localhost:4567
を開き、「Hello, world!」と表示されることを確認します。
MySQLのセットアップ
MySQLコンテナの追加
-
docker-compose.ymlに設定追加
docker-compose.ymlservices: ... db: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: password volumes: - db_data:/var/lib/mysql volumes: ... db_data:
-
Dev Containerを再起動
-
MySQLコンテナへの接続確認
mysql -h db -u root -ppassword
アプリケーションからMySQLにアクセスできるようにする
-
docker-compose.ymlに環境変数を追加
docker-compose.ymlservices: ... web: image: mysql:8 environment: DATABASE_HOST: db DATABASE_USER: root DATABASE_PASSWORD: password DATABASE_NAME: template-sinatra_development
-
GemfileにMySQL関連のGemを追加
Gemfile... gem "mysql2", "~> 0.5.6"
-
接続確認用のルートを追加
index.rbget '/health_check' do Mysql2::Client.new( host: ENV.fetch('DATABASE_HOST'), username: ENV.fetch('DATABASE_USER'), password: ENV.fetch('DATABASE_PASSWORD') ) 'OK' rescue StandardError => e status 500 e.message end
-
動作確認
ブラウザでhttp://localhost:4567/health_check
にアクセスし、"OK"と表示されることを確認。
DB作成タスク
-
Rakefileを作成
require 'rake' require 'mysql2' namespace :db do desc 'データベースを作成します' task :setup do begin # MySQLに接続 client = Mysql2::Client.new( host: 'localhost', username: 'root', password: 'password' ) db_name = 'template-sinatra_development' client.query("CREATE DATABASE IF NOT EXISTS #{db_name}") puts "データベースを作成しました: #{db_name}" rescue Mysql2::Error => e puts "エラーが発生しました: #{e.message}" ensure client&.close end end desc 'データを追加します' task :seed do begin db_name = 'template-sinatra_development' client = Mysql2::Client.new( host: 'localhost', username: 'root', password: 'password', database: db_name ) client.query(<<~SQL) CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255) ); SQL client.query("INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')") client.query("INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com')") puts 'サンプルデータを追加しました' rescue Mysql2::Error => e puts "エラーが発生しました: #{e.message}" ensure client&.close end end end
-
DB作成とデータの追加
bundle exec rake db:setup bundle exec rake db:seed
データを表示する
-
以下のコードをindex.rbに記述
index.rb# データベースクライアントを初期化 DB_CLIENT = Mysql2::Client.new( host: ENV.fetch('DATABASE_HOST'), username: ENV.fetch('DATABASE_USER'), password: ENV.fetch('DATABASE_PASSWORD'), database: ENV.fetch('DATABASE_NAME') ) # クエリ結果をシンボルで取得 DB_CLIENT.query_options.merge!(symbolize_keys: true) # ユーザー一覧を表示するルート get '/users' do users = DB_CLIENT.query('SELECT * FROM users') # HTMLレスポンスを作成 response = <<~HTML <h1>Users List</h1> <ul> HTML users.each do |user| response += "<li>#{user[:name]} (#{user[:email]})</li>" end response += '</ul>' response end
-
動作確認
ブラウザでhttp://localhost:4567/users
にアクセスし、usersテーブルに登録されたユーザー一覧が表示されることを確認。
以上で、Dev Containerを使用したSinatra開発環境(MySQL対応)の構築が完了しました。
サンプルコード
これまでの内容に加え、以下を実装したテンプレートプロジェクトです。
- Rspecを使ったテストの追加
- dotenvを使用した環境変数の切り替え対応
- Sequelを使用したマイグレーション機能の追加
- GitHub Actionsを利用したCI/CDの設定
参考資料
Discussion