7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Dockerで最低限のrails開発環境をコツコツ構築してみる〜第1章〜

Last updated at Posted at 2019-03-31

はじめに

コツコツと環境構築する様をアウトプットしていきます。

ゴール

いつものやつが表示されるまで
rails.png

環境

  • OS : macOS Mojave 10.14.3
  • Docker : 18.09.2

準備

ディレクトリ作成

$ mkdir rails_minimum
$ cd rails_minimum

Dockerfile作成

$ touch Dockerfile

今回は元となるイメージとしてruby:2.5.1を指定します。

Dockerfile
# 元となるイメージの指定
FROM ruby:2.5.1
FROM [イメージ名]:[タグ] 元となるイメージの指定

イメージをビルドする

まずは今あるイメージを表示してみます。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

何もしていないので、何もありません。
minimumという名前を付けてDockerfileを元にイメージをビルドします。
タグを指定することでイメージのバージョンを管理することができますが、今回は特にタグの指定はしないのでデフォルトのlatestになります。

# docker build [Dockerfile配置ディレクトリ]
$ docker build . -t minimum
オプション 説明
-t [イメージ名]:[タグ] イメージ名、タグの指定

イメージがビルドされました!

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ruby                2.5.1               3c8181e703d2        5 months ago        869MB
minimum             latest              3c8181e703d2        5 months ago        869MB

コンテナを起動する

今あるコンテナを表示してみます。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
オプション 説明
-a 全てのコンテナを表示

何もしていないので、何もありません。
先ほどビルドしたminimumというイメージからminimumという名前をつけてコンテナを作成します。

# docker create [イメージ名]
$ docker create --name minimum -it minimum
オプション 説明
--name [コンテナ名] コンテナ名の指定

コンテナができました!

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
fed23d01ed83        minimum             "irb"               8 seconds ago       Created                                 minimum

が、STATUSがCreatedでは起動はしていないので起動させます。

# docker start [コンテナ名]
$ docker start minimum

STATUSがUpになりコンテナが起動しました!

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
fed23d01ed83        minimum             "irb"               35 seconds ago      Up 3 seconds                            minimum

なお、docker runでコンテナ作成+コンテナ起動もできます。

# docker run [コンテナ名]
$ docker run -d --name minimum -it minimum
オプション 説明
-d バックグラウンドで起動
-i 起動時にコンテナの標準出力にアタッチ
-t 擬似ターミナル割り当て

コンテナ内で操作をする場合には-tが必須なようです。

コンテナを操作する

bashに入ってみます。

# docker exec [コンテナ名] [実行コマンド]
$ docker exec -it minimum bash
root@fed23d01ed83:/# 

プロジェクト用のディレクトリを作成してみます。

root@fed23d01ed83:/# mkdir app

作成したディレクトリに移動します。

root@fed23d01ed83:/# cd app
root@fed23d01ed83:/app#

railsプロジェクトを初期化してみます。

root@fed23d01ed83:/# rails new .
bash: rails: command not found

「railsなんてコマンドないよー」って怒られました。
ということでrailsに必要なgemをコンテナにインストールしなければなりません。

コンテナ内にrailsを導入する

railsに必要なgemをインストールするために、Gemfileを作成します。

root@fed23d01ed83:/app# touch Gemfile

Gemfileを編集します。
が、vimが使えませんね...。

root@fed23d01ed83:/app# vim Gemfile
bash: vim: command not found

コンテナ内にvimをインストールします。

root@fed23d01ed83:/app# apt-get update
root@fed23d01ed83:/app# apt-get -y install vim

vimが使えるので、Gemfileを編集します。
今回のrailsのバージョンは5.1.6にします。

root@fed23d01ed83:/app# vim Gemfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '5.1.6'

bundle経由で、Gemfileを元にrailsに必要なgemをインストールします。

root@fed23d01ed83:/app# bundle install

railsに必要なgemがインストールされたようです。
railsコマンドが使えるので、バージョンを確かめておきます。

root@fed23d01ed83:/app# rails -v
Rails 5.1.6

railsプロジェクトを初期化する

railsプロジェクトを初期化します。
すでにGemfileが存在するため、Gemfileが競合します。
上書いていいかを聞かれた場合は'y'を入力して下さい。
※-fオプションで強制的に上書くこともできます。

root@fed23d01ed83:/app# rails new .

無事作成できました。色々とできていますね。

root@fed23d01ed83:/app# ls
Gemfile  Gemfile.lock  README.md  Rakefile  app  bin  config  config.ru  db  lib  log  package.json  public  test  tmp  vendor

これでコンテナ内でrailsプロジェクトを初期化することができましたが、これではコンテナを削除してしまえば全て消えてしまいますし、なにより毎回こんなことをするのは面倒です。
ここからはDockerfileを改善していきます。

Dockerfileを改善する

まずは作成したコンテナを思い切って削除してしまいましょう。

root@fed23d01ed83:/app# exit

# docker stop [コンテナ名]
$ docker stop minimum

# docker rm [コンテナ名]
$ docker rm minimum

イメージも削除します。

# docker rmi [イメージ名]
$ docker rmi minimum

ここで、今存在するコンテナとイメージを表示してみます。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ruby                2.5.1               3c8181e703d2        5 months ago        869MB

minimumイメージを削除しただけなので、rubyイメージは残っていますが、元となるrubyイメージ自体には変更を加えないので、消す必要はありません。
イメージをビルドする際にすでにローカルに存在している場合はダウンロードせず、ローカルのイメージを利用してくれます。

処理をDockerfileに記述していきます。
が、全てをDockerfileに記述するわけではなく、一部はホスト側準備をします。

まずはGemfileを作成します。内容は先ほどと同じです。

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.1.6'

空のGemfile.lockも作っておきましょう。

Dockerfileを編集します。

Dockerfile
# FROM 元となるイメージ
FROM ruby:2.5.1

ENV APP_ROOT /app

# 作業ディレクトリを指定
# 指定したディレクトリが存在しない場合には作成してくれる
WORKDIR $APP_ROOT

# Gemfile、Gemfile.lockコピー
COPY Gemfile $APP_ROOT
COPY Gemfile.lock $APP_ROOT

# Gemfileを元にgemをインストール
RUN bundle install
説明
ENV [変数名] [値] 環境変数を定義する
WORKDIR [コンテナ内ディレクトリ] コンテナ内の作業ディレクトリを指定
RUN [実行コマンド] イメージビルド時にコマンドを実行
COPY [ホスト側コピー元] [コンテナ内コピー先] ホスト側からコンテナ内にコピー

一度イメージを作成してみます。

$ docker build . -t minimum

このタイミングで、先ほどのgemがインストールされた状態のイメージが作成されます。
コンテナを起動させます。
このとき、ボリュームの指定をすることで、指定したディレクトリでの編集が共有されます。

$ docker run -d --name minimum -it -v $PWD:/app minimum
オプション 説明
-v [ホスト側絶対パス] [コンテナ側絶対パス] ボリュームの指定

コンテナに入ります。

$ docker exec -it minimum bash

先ほどWORKDIRで指定したディレクトリがカレントディレクトリになっていることがわかります。
railsプロジェクトを初期化します。

root@888d61342746:/app# rails new -f .

ボリューム指定をしているため、ホスト側にもrailsのファイル群が作成されています。

$ ls
Dockerfile      Gemfile.lock    Rakefile        bin             config.ru       lib             package.json    test            vendor
Gemfile         README.md       app             config          db              log             public          tmp

サーバーを立ち上げてみます。

root@888d61342746:/app# rails server -d

エラーが出たかと思います。
railsの実行環境にはサーバーサイドでのJavaScript実行環境が必要(assetまわりのコンパイルで?)なようなのでnodejsをインストールします。

root@888d61342746:/app# apt-get update
root@888d61342746:/app# apt-get install -y nodejs

再度、サーバーを立ち上げる

root@888d61342746:/app# rails server -d

これで、晴れてサーバーが起動しました。
なにも考えずいつも通りブラウザからlocalhost:3000を表示してみると...アクセスできません!!
ブラウザからlocalhost:3000にアクセスした際にコンテナ内に立ち上がっているサーバーにアクセスできるように設定する必要があります。

localhost:3000でサーバーにアクセスできるようにする

一旦サーバーを止めます。
バックグラウンドでサーバーを起動している場合、tmp/pids/server.pidにサーバーが利用しているプロセス番号が書かれているので確認し、直接killします。

root@888d61342746:/app# cat tmp/pids/server.pid
863
root@888d61342746:/app# kill 863

コンテナを止め、削除します。

root@888d61342746:/app# exit
$ docker stop minimum
$ docker rm minimum

3000番ポートの開放、ポートの割り当て設定をしつつ、コンテナを起動します。

$ docker run -d --name minimum -it -v $PWD:/app -p 3000:3000 --expose 3000 minimum
オプション 説明
-p [ホスト側ポート番号]:[コンテナ側ポート番号] ポートの割り当て
--expose [コンテナ側ポート番号] ポートの開放

コンテナに入り、先ほどrails new実行時に自動的に実行されたbundle installによってインストールされたgemが現在のコンテナには存在しないのでgemのインストールをします。
nodejsも消えてしまっているのでインストールし直します。

root@41febcaa682c:/app# bundle install
root@41febcaa682c:/app# apt-get update
root@41febcaa682c:/app# apt-get install -y nodejs

コンテナのbashに入り、外部からアクセスできる0.0.0.0を指定してサーバーを起動しなおします。

root@41febcaa682c:/app# rails server -d -b 0.0.0.0

ブラウザからlocalhost:3000にアクセスしてみると...できた!

rails.png

ひとまず、ゴールは達成。

もう少しだけDockerfileを改善していきます。

nodejsのインストールをイメージビルド時に行います。

Dockerfile
# FROM 元となるイメージ
FROM ruby:2.5.1

# 必要なものをインストール
RUN apt-get update
RUN apt-get install -y nodejs

ENV APP_ROOT /app

# 作業ディレクトリを指定
# 指定したディレクトリが存在しない場合には作成してくれる
WORKDIR $APP_ROOT

# Gemfile、Gemfile.lockコピー
COPY Gemfile $APP_ROOT
COPY Gemfile.lock $APP_ROOT

# Gemfileを元にgemをインストール
RUN bundle install

これで、イメージをビルドした段階でnodejsのインストールホスト側のGemfileに記述してあるgemのインストールが行われます。

docker-composeを利用したさらなる改善は第2章で。
Dockerで最低限のrails開発環境をコツコツ構築してみる〜第2章〜

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?