はじめに
今まで、全然理解できていなくて逃げてたDockerに関して、しっかり理解していこうと思います。
コレまで、便利なんだろうなと思いながらも、逃げてました。
なので、開発環境では使いこなせるスキルにまでは理解したいと思います。
あと、暗記してたDockerコマンドを1つ1つ理解していきます。
以下のような順番で勉強していきます。
- Dockerの概要(1/9)
- Dockerの基本操作(イメージの作成, コンテナの起動, 停止, 削除)(2/9)
- Dockerの基本操作(ログの出力, コンテナの中でプロセスを実行する方法, 使用していない Docker オブジェクトの削除)(3/9)
- Dockerfileを使用したサーバー構築(座学編)(4/9)
- Dockerfileを使用したサーバー構築(実践編)(5/9) 今ここ
- Docker Composeの概要(座学編)(6/9)
- Docker Composeのよく使う基本操作(7/9)
- Docker Composeを使ってRailsの環境を構築する(8/9)
- Docker上に構築したRailsをHeroku(本番環境)にデプロイ(公開)する(9/9)
実践してみよう「Dockerfileを使用したサーバー構築」
今回は、Rubyをベースイメージにして、
それを元にSinatra(Ruby製のWebアプリケーションフレームワーク)を導入して、
各種インストールして、webサーバを作ります。
で、その、webサーバーを動かす環境をDockerfileで作る方法を学んでいきます。
Dockerのイメージを用意しよう
Dockerfileが用意できれば、そこからDockerイメージを作ることができます。
Dockerイメージを起動させることで、コンテナが作られます。
(似たようなこと言いますが)今回は、最終的にローカルPC上ではなくて、コンテナ上にwebサーバーを作っていきます。
ディレクトリの用意
src/
├ main.rb
└ Gemfile
Dockerfile
Gemfileには、Sinatraを導入する記述をします。
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'sinatra'
この記述は下記を参考
続いてDockerfileを書いていきますが、いきなりDockerfileにwebサーバとなるコンテナが立ち上がるように書くのではなく
まずは、コンテナ内でサーバが作れるか確認しつつ確かめましょう。
なので、インタラクティブモードでコンテナに入れるようなDockerfileを作成します。
Dockerfileを書いていきます
前の記事でも詳細に説明しましたが、改めてDockerfileとは何かを説明します。
Dockerfileとは、指定したベースのイメージに対して、どんな作業をさせるかを記載するファイルです。
# ベースイメージ
FROM ruby:2.7
# 作業をどこでやるかの指定(場所はどこでもいい)
WORKDIR /var/www
# 使用するソースコードをDockerコンテナ内にコピー
# ローカルの環境にあるsrc/ を dockerコンテナ内の /var/www にコピーする
COPY ./src /var/www/
# dockerの実行コマンド
CMD ["/bin/bash"]
Dockerイメージの作成
docker image build -t sample/sinatra:latest .
Dockerコンテナの作成・起動
docker container run -it -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
sample/sinatra:latest
これはイメージ名です。
-v
は、ボリュームのオプションです。これは、ローカルPCの./src
以下を、dockerコンテナ内の/var/www
に同期させるという意味です。
これをしないと、アプリケーション側のコードを更新してもdockerコンテナ内のコードが反映されないので指定しました。
-p
sinatraのポートはデフォで4567なので。ローカルもそれに併せて4567
にした。
-it
の説明は前の記事で書いたので、そちらを参照してください。
実行すると、Dockerコンテナ内でインタラクティブモードで起動します。
Dockerファイルにあるコマンドが CMD ["/bin/bash"]
bash というシェルを起動しているので、何かしらコマンドが実行できる状態になっております。
Dockerコンテナ上でDockerファイルに書くコマンドが実際に動くか確かめる
Dockerファイルに、webサーバーがちゃんと起動するか確かめる目的で、Dockerfileに直接書く前に
Dockerコンテナ内で実行できるかを確かめていきます。
root@eb497419aa28:/var/www# ruby -v
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux]
root@eb497419aa28:/var/www# ls
Gemfile
ためにし、rubyのバージョンを確かめたり、ls
コマンドを打ったりしました。
ls
の結果は、なぜGemfile
だけかわかりますか?
それは、Dockerfile内に書いた WORKDIR /var/www
作業ディレクトリを指定して COPY ./src /var/www/
の右側の部分、/var/www
この配下にローカルPCの.src/
配下を同期させているので。
Dockerコンテナ上でライブラリをインストールしていく
どこにライブラリをインストールするかの指定です。
bundle config --local set path 'vendor/bundle'
実際にインストールするコマンドは以下
bundle install
Railsを使われる方にとってはお馴染みなコマンドですね。
うまくインストールできたら今度は簡易的なWebサーバを作成をRubyで書いていきます。
Sinatra(ruby)で簡易的なサーバを作成
require 'sinatra'
# 初期設定(どんな通信でも受け取れるようにIPアドレスを以下のように指定)
configure do
set :bind, '0.0.0.0'
end
# TOPページにアクセスしたら文字列を出力する
get '/' do
'Hello world!'
end
詳しい説明は以下に任せます。
Dockerコンテナ上のRubyを動かします
root@eb497419aa28:/var/www# bundle exec ruby main.rb
[2021-09-24 10:54:06] INFO WEBrick 1.6.1
[2021-09-24 10:54:06] INFO ruby 2.7.4 (2021-07-07) [x86_64-linux]
== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick
[2021-09-24 10:54:06] INFO WEBrick::HTTPServer#start: pid=50 port=4567
Gemfileを使った処理を動かすときはbundle exec
をつけます。
webサーバが立ち上がったことが確認できました。
http://localhost:4567/
にアクセスして、'Hello world!'
が出力されたらOKです。
Dockerコンテナないでうまく動いたので、今度は、この情報をDockerfileに記入して同じ挙動になるか試しましょう。
Dockerfile内でサーバー構築コマンドをなどを記載していく
必要な処理は
- ライブラリの追加(
bundle config --local set path 'vendor/bundle'
) - rubyの実行(
bundle exec ruby main.rb
)
ですね。これをDockerfile内に書くだけです。
コマンドの実行はRUN
でやります。
FROM ruby:2.7
WORKDIR /var/www
COPY ./src /var/www/
RUN bundle config --local set path 'vendor/bundle'
RUN bundle exec ruby main.rb
CMD ["bundle", "exec", "ruby", "main.rb"]
RUN
が重複してるので&&
で、続けて書くこともできます。
FROM ruby:2.7
WORKDIR /var/www
COPY ./src /var/www/
RUN bundle config --local set path 'vendor/bundle' && bundle install
CMD ["bundle", "exec", "ruby", "main.rb"]
完成しました。
では、前のコンテナを削除して、イメージを作り直して、再度コンテナを作成・起動させましょう。
サーバー(ctrl + c
)を止めてexitして、以下を実行します。
コンテナの削除
docker container rm sinatra
これでコンテナが削除されました。では、Dockerイメージを作り直します。
docker image build -t sample/sinatra:latest .
イメージの作成は同じコマンドです。
イメージが作成できたら、今度はコンテナを起動させます。
docker container run -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
今回は、-it
消しています。なぜなら、今回は、コンテナ内でshellを実行させるつもりはないので。
今回は、コンテナを実行する = サーバを起動させる
だけなので、-it
は消しています。
コンテナが起動したということは、サーバが立ち上がったということなので、再度、ブラウザ立ち上げて以下のポートでアクセスします。
http://localhost:4567/
アクセスして Hello world!
が出力されたら、今度は、Dockerコンテナ上のサーバーからアクセスが成功したことになります。
以上です。
アウトプット100本ノック実施中