M1 Macbookを使ってポートフォリオを作ろうと思い、Virtual Boxで開発環境を作成しようとするとVirtual Boxが使えないことが発覚したので、Dockerを使って開発環境を構築しようとした。
しかし、色んなサイトの作成方法を真似しても上手くいかず、Dockerの公式ドキュメントを参考にしたところ、Yay! You’re on Rails!の画面を出すことができた。
手こずってしまった原因がDockerへの理解不足だったため基本的な概念を備忘録として記載しようと思う。
表現が不適切なところも多々あると思うので、ご指摘くだされば幸いです。
まずはイメージ図を頭に入れる
引用
https://coinbaby8.com/docker-beginner.html
Dockerイメージという雛形があって、それを使ってDockerコンテナという開発環境を作るといったことを頭に入れた。
Dockerイメージの中にはアプリコードやOSというものが中に含まれる。
そのイメージはどこにあるのかというとDockerHubというところに用意されているので、それを使い、Dockerコンテナという環境を作るのが自分のしたい開発環境の構築だと認識した。
続いて理解したのが下図
引用
https://docs.docker.jp/engine/introduction/understanding-docker.html
流れとしては
①クライアントがデーモンにコマンドを実行するように依頼して、デーモンがレジストリからDockerイメージをもらってくる。
②そのDockerイメージを使ってDockerコンテナを作る
このように認識した。
クライアント:依頼主のこと(イメージやコンテナを作ってほしいという依頼をしているから作業者のこと?)
デーモン:コマンドを実行する常駐プログラムのUNIX系OSにおける呼び名
これらを頭に入れて公式ドキュメントに沿って環境を作る。
https://docs.docker.com/samples/rails/
準備するものは
Dockerfile
Gemfile
Gemfile.lock
entrypoint.sh
docker-compose.yml
これらはVScodeでファイルの作成から作る。
VScodeの使い方がわからない方はドットインストールのVScodeの使い方の動画を参考にすると良いと思う。
ターミナルも見れるのでとても便利
ピンクで囲ったところでファイルを作成できるので、上記のファイルを作成する。
私はローカルのデスクトップにRailsというフォルダを作成して、その中に上記5つのファイルを作成した。
Dockerfileの中身から記載していく。
ファイル名のDは大文字なので注意。
# syntax=docker/dockerfile:1
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
Gemfileの中身を記載する。
source 'https://rubygems.org'
gem 'rails', '~>5'
Gemfile.lockは中身を記載しない。
公式ドキュメントだとターミナルで下記のコマンドでGemfile.lockを作成している。
touch Gemfile.lock
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
version: "3.9"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
これらが作成できたらターミナルで以下のコマンドを入力する。
docker-compose run --no-deps web rails new . --force --database=postgresql
このコマンドを実行したら、自動でフォルダやファイルが作成されたと思います。
このコマンドの意味はrunコマンドを介して指定したサービスのコンテナ内でコマンドを実行できる。
runコマンドではimageの構築から、コンテナの構築・起動までしてくれるが、引数でサービスを指定しないと失敗します。
rails newをコンテナ内でやってくれている認識。
次にこちらのコマンドを入力するのですが、
docker-compose build
このコマンドの意味はimageを構築するが、コンテナは作成しない。
上のコマンドでimageの構築から、コンテナの構築・起動までしてくれたのになぜ下記のコマンドを入力する必要があるのか。
ドキュメントを見るとこのような記載がありました。
「MacやWindowsでDockerを実行している場合、rails newで生成されたファイルを含む全てのファイルの所有権を既に持っているはずです。
新しいGemfileを手に入れたので、イメージを再度ビルドする必要があります。(再構築が必要になるのは、このときと、GemfileやDockerfileを変更したときだけです。)」
新しいGemfileになった場合、ビルドが必要みたいなので、上記コマンドを実行する。
新しくできたdatabase.ymlの中身を書き換える。
configの配下にある。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: password
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
そしてターミナルでコマンドを入力する。
docker-compose up
最後にデータベースを作成する。
docker-compose run web rake db:create
これらが上手くいったらURLバーに以下を入力する。
するとこのような画面が出るはず。
次回からはDocker Desktopというアプリを入れることでGUIでコンテナの起動とデータベースの起動ができるようにした。
ここで起動したり止めたりができる。
M1チップのMacかインテルチップのMacかでインストールが変わるので注意。
プログラミング初心者からすると日本語の記事が多いRuby選んだのに英語読むの?と思うかもしれないが、公式ドキュメントを読む大切さを知った。
今後は英語の記事やサイトも読めるようにしていきたい。