今回達成すること
自身のPC上に作業ディレクトリを作り、その中にDockerイメージに必要なDockerfileを作成し編集していきます。
今回はRails用のDockerfileを作成します。
DockerでRails6を動かすGemfileの編集、Dockerfileのコード解説、またAlpine Linuxとは?にも触れています。どうぞお楽しみください。
作業ディレクトリを作成する
作業ディレクトリを作成する場所へ移動
ターミナルを開いて、作業ディレクトリを作成する場所へ移動してください。
ちなみに筆者の場合は/development/docker
の直下に作成します。
$ cd development/docker/
作業ディレクトリの作成
作業ディレクトリを作成し、そのディレクトリへ移動します。
自由に名前を決めてください。(筆者の場合はudemy_demoapp_v1)
$ mkdir udemy_demoapp_v1 && cd $_
-
$_
... 直前のコマンド引数を取得します。ここでは「udemy_demoapp_v1」を取得しています。
以下、作業ディレクトリはターミナル上で「root」と表現します。
Gitの初期化
最初にGitの初期化を行います。
初期化はどのタイミングでも問題ありませんが、一番最初にする癖を付けておきましょう。
root $ git init
Rails、Nuxt.jsディレクトリを作成する
各アプリを格納するディレクトリの作成
続いてRailsとNuxt.jsのアプリケーションを格納する2つのディレクトリを作成します。
root $ mkdir {api,front}
-
{}
... 波カッコで囲むと一度に複数のディレクトリやファイルが作成できます。注意する点は、カンマの後にスペースを入れるとエラーになります。
スペース無しで実行しましょう。
確認しておきましょう。
root $ ls
api front
RailsのDockerfileを作成する
Dockerfile、Gemfile、Gemfile.lockを作成
RailsのDockerイメージを作るために、3つのファイルを準備します。
- Dockerfile
- Gemfile
- Gemfile.lock
apiディレクトリに移動しましょう。
root $ cd api
Dockerfile、Gemfile、Gemfile.lockの3つのファイルを作成します。
api $ touch {Dockerfile,Gemfile,Gemfile.lock}
確認しておきましょう。
api $ ls
Dockerfile Gemfile Gemfile.lock
Gemfileの編集
まずは
api/Gemfile
source 'https://rubygems.org'
# 2022.04.04編集。
# Udemyを受講中の方へ。v6.0系はバグの温床となり得るため、v6.1系を使用してください。
# gem 'rails', '~> 6.0.0'
gem 'rails', '~> 6.1'
-
~> 6.0.0
... Railsのバージョン 6.0.0 ~ 6.1.0未満で、最新のものがインストールされます。ちなみに
~> 6.0
と指定した場合は、6.0.0 ~ 7.0.0未満の最新Railsがインストールされます。
Dockerfileの編集
続いて
2020年6月13日 追記
$ docker-compose build
コマンドでエラーが出るため下記コードを修正しました。すみません。
- 修正前 ... RUN echo HOME=>${HOME}
- 修正後 ... RUN echo ${HOME}
下記は修正済みのコードとなります。
api/Dockerfile
FROM ruby:2.7.1-alpine
ARG WORKDIR
ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata postgresql-dev postgresql git" \
DEV_PACKAGES="build-base curl-dev" \
HOME=/${WORKDIR} \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
# ENV test(このRUN命令は確認のためなので無くても良い)
RUN echo ${HOME}
WORKDIR ${HOME}
COPY Gemfile* ./
RUN apk update && \
apk upgrade && \
apk add --no-cache ${RUNTIME_PACKAGES} && \
apk add --virtual build-dependencies --no-cache ${DEV_PACKAGES} && \
bundle install -j4 && \
apk del build-dependencies
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]
Dockerfileの参考元
Dockerfileを一つ一つ説明するぞう
それでは上記Dockerfileの説明に入ります。
初めて見た方は何が何やら訳が分からないと思いますが、どうぞご安心を。(筆者もそうでした。)
FROM <ベースイメージ>
Dockerfileには「コンテナをどのイメージから生成するか」を必ず記入しなければなりません。
このイメージをベースイメージと呼び、FROM命令で指定します。
ruby:2.7.1-alpine
ここでベースイメージを指定しています。
-
ベースイメージの書き方 => <イメージ名>:<タグ名>
イメージ名はRailsの基となるRubyを指定しています。
タグにはRubyのバージョンを指定しています。
-
タグ名の読み方 ... <イメージのバージョン> - <OS><OSのバージョン(任意)>
Alpine LinuxベースのRubyを使用しています。
OSのバージョンを指定しない場合は最新のAlpine Linuxが使用されます。
Alpine Linuxについては↓下で説明します。
ベースイメージのRubyバージョンを調べる手順
ちょっと豆知識。これからのプログラミング人生のために。
Rubyのバージョンは開発時点の安定版を使用するようにしましょう。
以下の手順でバージョンを調べます。
-
まず、Rails6に必要なRubyのバージョンを知る。
Railsガイド => Ruby 2.5.0以降が必要
-
次にRuby 2.5.0以上の安定版を知る。
Ruby => 安定版は 2.7.1
-
最後にRuby 2.7.1のベースイメージを調べる。
Docker Hub => 2.7.1-alpineを採用
ARG <変数名>
Dockerfile内で使用する変数名を指定します。
ここでは「WORKDIR」と言う変数名を宣言をしています。
これから先「docker-compose.yml」内で指定しますが、先にネタバラシをすると、ここには「app」と言う文字列が入ります。
ENV <変数名=値>
Dockerイメージで使用する環境変数を指定します。
ENVを使って設定した環境変数は、イメージからコンテナへ渡されます。
コンテナへ渡されると、コンテナ内で起動したアプリケーションで参照することができます。
RUN <実行コマンド>
ベースイメージに対して何らかのコマンドを実行する場合に使用します。
例えば echo ${HOME}
は「${展開した環境変数}」の文字列を出力しろ。と言うコマンドです。
Dockerfile内で変数を展開する場合は、${変数名}
、もしくは$変数名
と書きます。
WORKDIR <ディレクトリパス>
Dockerfileで定義した命令を実行する、コンテナ内の作業ディレクトリパスを指定します。
ここで指定したディレクトリパスの中にRailsアプリが作成されます。
COPY <ローカルのファイルパス> <Dokerイメージのファイルパス>
ローカルファイルをイメージにコピーする命令です。
ローカルファイルとは自分のPC上にあるファイルです。
-
Gemfile*
このアスタリスクは「Gemfileで始まるファイル名を全てコピーする」という指定になります。
つまり、ローカルのGemfileとGemfile.lockを指定しています。
-
./
コピー先のパスを絶対パス、もしくは相対パスで指定します。
ここでは相対パスを指定していて、「
WORKDIR
の直下にコピー」されます。絶対パスの場合は
/app
のように記入します。デフォルトのパスは
/
です。
apk
Alpine Linuxのコマンドです。
Linuxコマンドのapt-get
が使用されている場合は、ベースイメージがAlpineでは無いと言う事です。
混乱しやすいところですが「Alpine = apk
コマンド」と覚えておきましょう。
参考 Docker docs
apk update
利用可能なパッケージの最新リストを取得するためのコマンドです。
apk
コマンドでパッケージをインストールする場合、必ずと言っていいほど先頭に追加します。
「まず初めにupdate
してパッケージをインストールする」と覚えておきましょう。
参考 Alpine Linux
--update-cacheオプションは必要ない。
ここで補足。筆者がコピペで済まして間違っていたトコ。
apk add
コマンドの--update-cache
オプションは、apk update
と同じく「利用可能なパッケージの最新のリストを取得するためのコマンド」のオプションバージョンです。
apk update
を実行したのちにインストールするパッケージには、--update-cache
オプションを付ける必要はありません。
apk upgrade
インストールされているパッケージをアップグレードします。
当初、インストール後に実行すべきでは?と思いましたが、コマンドを確認するとインストール前に書いてもちゃんとアップグレードされていました。
apk add
パッケージをインストールするコマンドです。
--no-casheオプション
ローカルにキャッシュしないようにする、add
コマンドのオプションです。
コンテナを軽量に保つために使用します。
--virtualオプション <名前>
add
コマンドのオプションです。
このオプションを付けてインストールしたパッケージは、一まとめにされ、新たなパッケージとして扱うことができます。
パッケージのパッケージ化、ヘルプでは「仮想パッケージ」と呼んでいます。
この仮想パッケージを呼び出すには、指定した<名前>で呼び出します。
ここではbuild-dependencies
と言う名前を付けています。
実行した後に削除する、いわゆる「使い捨てパッケージ」をインストールする場合に良く使われます。
bundle install -j4
Railsに必要なGemをインストールするためにbundle installコマンドを実行しています。
-
-j4
bundle installのオプションで、
--jods=4
の別名です。並列処理でインストールが高速化されるって!!(初耳)
apk del
パッケージを削除するコマンドです。
先ほど--virtual
オプションで指定した、仮想パッケージを一括削除しています。
build-base
とcurl-dev
はRailsの起動自体に必要ないので削除してんだね。
COPY . .
ローカルにある全てのファイルをイメージにコピーしています。
それぞれ相対パスで指定しています。
CMD [実行したいコマンド]
生成されたコンテナ内で実行したいコマンドを指定します。
Railsを起動するためのrails server
コマンドを実行しています。
-
-b 0.0.0.0
rails serverのコマンドオプションとなります。
railsのプロセスをどのipアドレスにバインドするかを指定します。
ここではlocalhostのipアドレス「127.0.0.1」を「0.0.0.0」にバインドしています。
-
なぜこんな事をするのか?
仮想環境で起動したRailsは、localhostのipアドレス「127.0.0.1」でアクセスできません。
そこで仮想外部からアクセスできるように、ip「0.0.0.0」に紐付けをする必要があるのです。
これにより、自分のPC上のブラウザでRailsにアクセスできるようになるのです。
もっと詳しく為になる rails s -b 0.0.0.0 のオプション-bの意味
(Dockerfileの説明終わり)
ところでAlpine Linuxって...???
忘れてました。Alpine Linuxの説明を。
Alpine Linuxとは?
Linuxディストリビューションの一つで、非常に軽量であることが特徴です。
Linuxの概要
Linuxそのものは「カーネル」と呼ばれるOSの中核部分を担う役割を持ちます。
よくLinuxカーネルと呼ばれますが、これはLinuxそのものを指します。
- Linux = Linuxカーネル
このLinuxカーネル単体だけではOSとして成り立たたず、その他のソフトウェアが組み合わさって初めてOSとしての機能を持ちます。
- Linuxカーネル + 色んなソフトウェア = OS
Linuxディストリビューションとは?
-
「Linuxカーネル + 色んなソフトウェア」を一まとめにし、
-
利用者が簡単にOSとして利用できるようにしたもの、
-
もしくは、このOSの配布方法のことを言います。
-
Linuxディストリビューション = 「Linuxカーネル + 色んなソフトウェア」が一まとめになったOSのこと(もしくは配布方法のこと)
Alpine Linuxとは?のまとめ
Alpine Linuxとは、
- 非常に軽量な
- Linuxカーネルと色んなソフトウェアが一まとめになった
- OSのことです。
参考
ディストリビューション (distribution) - IT用語辞典
↓ここすごく分かりやすかった!
まとめ
今回は
- 開発に必要な作業ディレクトリを作り、
- Railsのイメージ作成に必要なDockerfileとGemfileを編集
しました。
覚えることが多々ありましたが、作業的には1ミリくらいの進捗です。とほほ。。。
ポイントをまとめておきましょう。
- Dockerfile
ENV
で指定した値はコンテナ内で参照できるapk
はAlpine Linuxのコマンドapk update
をすれば--update-cache
オプションは必要ない--no-cache
オプションは軽量なコンテナを実現する--virtual
オプションはすぐに削除するようなパッケージ群に指定する
- Alpine Linux
- Linuxと言う言葉は、Linuxカーネルを指す
- OSはLinuxカーネルだけでは動かない
- Linuxカーネルと色んなソフトウェアを一まとめにし、OSとして提供しているものを「Linuxディストリビューション」と言う
- Alpine Linuxとは、OSの一つで非常に軽量である
さて、次回は?
次は、Nuxt.js用のDockerfileを作成していきます。
お楽しみに〜!
修正情報
-
2020年11月25日
-d 0.0.0.0
を表記していたものを、-b 0.0.0.0
に修正しました。