前提
githubにリポジトリを作成しておく
Dockerをインストールしている
Dockerを使う理由
progateやrailsチュートリアルのみをやられている方にとって、いきなりDockerを使って開発環境を構築していきましょうと言われてもキツイと思うので、詳しい説明は別のところで行うにしても、簡単になぜdockerを使いたいのか説明しておきます。
dockerは簡単にいうと、これから作ろうとしているアプリケーションが動作するための使い捨ての環境を用意するためのものです。
通常、railsをインストールして動作させるには、localhostにmysqlをインストールして起動しておき、gemfileに書かれたgemをPCにインストールして、場合によってはそれ以外にも必要なライブラリが出てくるかもしれません。一人で開発している場合でも、このアプリケーションでしか利用しないようなものを自分のPCにインストールするのはちょっと抵抗があるかと思います。また、複数人で開発しているような場合、この面倒な開発環境の構築は全員が一度はやる必要があり、それぞれがすでに入っているライブラリの状態に応じて実行するコマンドが一定ではなくなってしまいます。
dockerはこのような問題を解決してくれます。
コンテナと呼ばれる使い捨ての環境をコードによって自動的に作成することができ、その中にアプリケーションを展開することで、アプリケーションでしか利用しないようなライブラリを自分のPCに直接インストールする必要がなくなりますし、複数人で開発している場合でも、コンテナを立ち上げることで同じ環境が提供されるので、全員が同じ手順でアプリケーションを起動することができるようになります。
開発環境を構築する
Dockerをインストールされていない方はここでdockerをインストールしておきましょう。
Dockerのインストール方法についてはdockerの公式のサイトがわかりやすいので、こちらでよいとおもいます。
注意点はwindowsとmac(intelやappleシリコン)によってインストールするものが変わるので、それぞれのosにあったものを選択するようにしてください!
インストールが完了したら早速開発環境を構築していきましょう。
アプリケーションのディレクトリに移動してください。
cd ./techport-rails-nextjs
私は、このディレクトリ内にnextjsのアプリケーションも作成してrailsとnextjsを同じgithubリポジトリで管理するような構成で開発を進めていきたいと思います。そのため、railsのアプリケーション名はbackendとします。
まずはbackendディレクトリを作成します
mkdir backend
Dockerfileの準備
作成したbackendディレクトリにDockerfileを作成します。
その中身は下記の通りです。
FROM ruby:3.2
ENV LANG=C.UTF-8 \
TZ=Asia/Tokyo
WORKDIR /app
RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client vim
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
CMD ["rails", "server", "-b", "0.0.0.0"]
簡単に書いてあることを説明しておきます
FROM ruby:3.2
→これはruby:3.2のdockerイメージベースにコンテナを作成するという意味です。ruby:3.2のイメージはdockerhubというところにデータが存在するのでそれを手元に用意してあげます
ENV LANG=C.UTF-8 \
TZ=Asia/Tokyo
→これはコンテナの環境変数に言語とタイムゾーンの設定をいれています。
WORKDIR /app
→これはコンテナの中にappというディレクトリを作成して、このディレクトリに移動してあげることを意味します。これによってコンテナ内部では/appディレクトリの中にrailsアプリケーションを構築していくことになります
RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client vim
→これはrailsを起動させるにあたって必要だったりあると便利なライブラリをインストールしてあげています。
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
→これは左側に書かれているGemfileやGemfile.lockをコンテナ内に/app/Gemfileや/app/Gemfile.lockとして作成してあげることを意味します。GemfileやGemfile.lockはまだ作成していないので後で作成します
RUN bundle install
→コンテナ内でbundle installを実行します
CMD ["rails", "server", "-b", "0.0.0.0"]
→コンテナが起動するタイミングでrails server -b 0.0.0.0を実行します。
GemfileとGemfile.lockの準備
GemfileとGemfile.lockをbackendディレクトリ内に作成します。
Gemfile.lockはいずれ、rails newされるタイミングで自動的に書き込まれるので、空でよいです。
Gemfileにはrailsのgemをインストールする必要があるので
source 'https://rubygems.org'
gem "rails", "~> 7.0.8"
とだけ書いておいてください
docker-composeの準備
先に作成したDockerfileを起動したりrailsで利用するmysqlデータベースを用意し、それらのコネクションを確立させるためにdocker-compose.ymlを作成します。
docker-compose.ymlを作成してdocker composeのコマンドでコンテナを立ち上げることで、一つのコマンドで複数のコンテナを立ち上げ、さらに立ち上げたコンテナ同士が同一のネットワーク内に置かれるのでコネクションが便利になります
というわけで作成しましょう。
ここでは、後でnextjsもdocker composeで同時に立ち上げたいと思っているので、backendディレクトリではなく、アプリケーション直下にdocker-compose.ymlを置きます。
もし、nextjsを同時に立ち上げる予定がない場合は、Dockerfileと同じ階層においてあげるでよいです。
その場合、これから記載する相対パスが少し変わるので、その点だけ注意してください
cd ../
touch docker-compose.yml
作成したdocker-compose.ymlには下記の通り記載してください
version: "3.8.1"
services:
db:
image: mysql:8.1.0
environment:
- MYSQL_DATABASE=techport
- MYSQL_ROOT_PASSWORD=password
volumes:
- mysql-db:/var/lib/mysql
ports:
- 3306:3306
backend:
tty: true
stdin_open: true
depends_on:
- db
build:
context: ./backend/
dockerfile: Dockerfile
ports:
- 3000:3000
volumes:
- ./backend:/app
command: rails server -b 0.0.0.0
volumes:
mysql-db:
driver: local
分量が多いのでさらにざっくり解説していきます
version: "3.8.1"
docker-composeのバージョンです
services:
db:
image: mysql:8.1.0
environment:
- MYSQL_DATABASE=techport
- MYSQL_ROOT_PASSWORD=password
volumes:
- mysql-db:/var/lib/mysql
ports:
- 3306:3306
railsが参照するデータベースのコンテナを用意します。
イメージにmysql:8.1.0を持ってきます。mysqlは一定の環境変数を入れておくことで、データベースを最初から作成したりDBにアクセスするためのアカウントの設定ができます。初期のデータベース名をtechport。rootユーザーのパスワードをpasswordにしています。
volumesはymlファイルの一番したのvolumes: …以下のところと関係します。これがあることで、使い捨てのコンテナではありますが、dbの中に作成されたデータたちはボリュームというところで管理されるようになり、コンテナを削除してもデータは残るので、また別でコンテナを作成してもデータが残っているような状態にできて非常に便利です。
portsでlocalhost:3306でアクセスできるようにします
backend:
tty: true
stdin_open: true
depends_on:
- db
build:
context: ./backend/
dockerfile: Dockerfile
ports:
- 3000:3000
volumes:
- ./backend:/app
command: rails server -b 0.0.0.0
depends_onでdbが立ち上がった後にこのbackendのコンテナが立ち上がるようにします。contextとdockerfileの設定で./backend/Dockerfileを起動するようにしています。
3000番ポートでアクセスできるようにします
volumes:
mysql-db:
driver: local
ボリュームと呼ばれるデータの格納先を用意しています。mysqlのコンテナが削除されてもそのデータは残すための置き場所です
rails newする
ここまで準備ができたらrails newしていきます。
dockerを利用しているので、コマンドは通常よりも長めになります
docker compose run backend rails new . -d mysql
docker composeでbackendのサービスを起動しつつ、rails new . -d mysqlを実行しています。
-d mysqlはデータベースにmysqlを利用することの指定です
途中でOverwrite /app/Gemfile? (enter "h" for help) [Ynaqdhm]
を聞かれたら、yを入れてenterでよいです
うまくいくと、非常に大量の新規ファイルが作成されると思います。
このまま、docker compose up –buildと、イメージを作成しつつ、コンテナを起動しようとすると、localhost:3000にはアクセスすることはできるのですが、railsのエラーになると思います。Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
これは、mysqlのsocketというファイルが見当たらず、railsがうまくdbとコネクションできていないようです。
データベースとのコネクションについてはbackend/config/database.ymlファイルに設定があるので、これをいろいろと編集する必要があります。
最終的には
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: db
development:
<<: *default
database: techport
このようになりました。
変更点は
passwordにpasswordを入れること
hostはlocalhostからdbにする
developmentのdatabseをtechport
にします。
データベースのパスワードはdocker-compose.ymlのMYSQL_ROOT_PASSWORDの値と合わせてください。また、hostはdocker-compose.ymlのservicesのデータベースの設定欄のキー名です
services:
db: // ←ここ
databaseの値はMYSQL_DATABASEの値と合わせてください。
これでもう一度、コンテナとイメージを作成します。
docker compose up --build
localhost:3000にアクセスして、railsの画面は開くことができたでしょうか?
このように表示されていれば成功です!!
コメント