🔴背景
SQL 第2版 ゼロからはじめるデータベース操作の第9章がアプリケーション(Java)とDBをつなげる旨の内容だったので、JavaをRubyに読み替えて、Dockerを使ってRuby側からDBのデータを取り出すところまでやってみた。
🟠ゴール
Rubyの実行環境のコンテナからpostgreSQLのコンテナに接続して、第1章~第8章で使っていたshohinテーブルから配列でデータを取り出して、コンソールに出力する。
本記事の使用バージョン
docker desktop 4.38.0
ruby 3.3(Docker公式イメージ)
postgreSQL latest (1/10現在)
🟡ファイル構成
sql_handson
├── README.md
├── docker-compose.yml
└── ruby
├── Dockerfile
├── Gemfile
├── Gemfile.lock
└── test.rb
*学習記録も兼ねていたので省略してるファイルも含めると冗長気味です。
🟢docker-compose.yml
services:
db:
image: postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql
ruby:
build:
context: ruby/
dockerfile: Dockerfile
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
depends_on:
- db
volumes:
pgdata:
db:
-
image: postgres: 本書で使うpsqlもすぐ使うことができました。 -
POSTGRES_PASSWORD: 必須
POSTGRES_PASSWORD
This environment variable is required for you to use the PostgreSQL image. It must not be empty or undefined.
-
volumes: Important changeより、バージョン18以上はpgdata:/var/lib/postgresqlを設定。
ruby:
context: ruby/: Dockerfileがdocker-compose.ymlと同じDirにないため、明示します。
dockerfile: Dockerfile: 使うDockerfileを明示します。
environment: db:への接続情報
🔵Dockerfile
FROM ruby:3.3
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["ruby", "test.rb"]
単純にDBを叩いてコンソールに出すだけなので超簡易的なDockerfile
🟣test.rb
公式のDescriptionにあるコードをテスト用に簡易的に変更。
#!/usr/bin/env ruby
require 'pg'
# Output a table of current connections to the DB
conn = PG.connect( dbname: 'sales' )
conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
puts " PID | User | Query"
result.each do |row|
puts " %7d | %-16s | %s " %
row.values_at('pid', 'usename', 'query')
end
end
https://github.com/ged/ruby-pg?tab=readme-ov-file#description
require "pg"
conn = PG.connect(
host: "db",
dbname: 'shop',
user: ENV["POSTGRES_USER"],
password: ENV["POSTGRES_PASSWORD"])
conn.exec("SELECT * FROM shohin;" ) do |res|
p res.to_a
end
#.envで管理している前提
🟤コンテナを起動してみる
docker-compose up --build
[{"shohin_id"=>"0001", "shohin_mei"=>"めっちゃかっこいいシャツ", "shohin_bunrui"=>"衣服", "hanbai_tanka"=>"1000", "shiire_tanka"=>"500", "torokubi"=>"2025-12-02"},]
# 一部レスポンス省略
できた✨✨✨
※test.rbでto_a(オブジェクトを配列に変換するメソッド)をつけ忘れないように注意
⚫引っかかったポイント
問題
Description通りにするとなぜかエラーが出る。
require "pg"
conn = PG.connect(
dbname: 'shop',)
conn.exec("SELECT * FROM shohin;" ) do |res|
p res.to_a
end
/usr/local/bundle/gems/pg-1.6.3-x86_64-linux/lib/pg/connection.rb:944:in `connect_start': connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory (PG::ConnectionBad)
解決方法
公式ドキュメントはローカル前提で同一ホストの接続のため、dbnameの明記だけでよい。しかし、今回は別コンテナ別ホストのため接続情報(host)を明記し、TCP接続する必要がある。
⚪まとめ
無事ゴールは達成したが、Dockerの理解はまだまだまだまだなので、もっとやるべきと感じる。
ORM(ActiveRecord)から学習を始めたため、素のSQLを書く機会がなく、今回学習に至ったが、全章やり切った。ハンズオンを違う言語や方法でやると思考力がつくと思うので、結構おすすめです。
🔴参考文献
- SQL 第2版 ゼロからはじめるデータベース操作 ミック 著
- https://hub.docker.com/_/postgres