Docker 入門

本記事の目的

本記事の目的は私が Docker のコマンドや仕組みを理解するためのものです。

今回は動画を利用した学習を行ったため、動画を追うのが精一杯で理解が難しい箇所が多くありました。

その解決策として、その動画で理解したことを整理するために記事に書き起こすことにしました。 記事後半に Docker を学習する際に実際に使ったコマンドやエラーを記録しています。

なお、今回は YouTube の 『 Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース 』という動画を参考に(写経)しています。

参考動画↓

Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース - YouTube

チャンネル↓

https://www.youtube.com/channel/UC452hry4DI_pDn_CVT9ZKhQ

学習手法

動画を追いながら Docker に触れる。動画一周では理解できていないことが多かったため二周した。

一周目は手を動かして操作に慣れるための写経。

二周目はコマンドや仕組みを理解するための寄稿。(本記事)

学習するに至った経緯

Docker で簡単に Laravel の環境構築がしたかったため。

使用環境

M1 Mac ( Monterey ver. 12.2.1 )

VSCode

DockerDesktop

iTerm2

所要時間:約3日

余談

今回は YouTube の動画を参考に学習しました。最近 Connpass などで講義をよく見ていますが、オンライン形式に慣れてしまえば YouTube でもある程度までは問題なく技術の獲得ができるように思いました。ただし、YouTube の動画を参考にする際は、その動画(投稿者)の信頼性と、いつの動画か(バージョン等の環境がどれだけ違うのか、取り扱っている技術が現在も主流の技術なのか)の2点によく注意する必要があるということを念頭に置いておかなければならないと思います。

以下、今回使用したコマンドやエラー

事前準備

今回は DockerDesktop や VSCode はインストール済みのため省略。

Docker とは

Docker の利点はアプリの環境構築・開発・運用の簡易化である。

OS, ライブラリ, アプリケーションをパッケージ化して配布することができるため、「複数人での開発時のメンバー間」「本番環境とテスト環境」の環境の差異をなくすことができる。

Docker を使ってみる

Docker を起動してみる

docker run hello-world

コンソールに Hello from Docker!が表示されると成功。

ここで起きたこと

イメージからコンテナを作成し、コンテナを起動した。

※イメージとはアプリコードやOS、ライブラリをまとめたパッケージのこと。

具体的な仕組み

  1. クライアント(コンソール)がdocker runでホストの「dockerデーモン」を 起動。
  2. デーモンがオンライン上の「dockerレジストリ」から「dockerイメージ」を取得。
  3. 取得したイメージからコンテナを作成して、コンテナを起動。

アプリを作成・実行

ここではイメージとコンテナの操作を学習する。

アプリケーションを作成して、Dockerで実行する基本的な流れ

  1. アプリコードの作成
  2. Dockerfile の作成
  3. イメージの作成
  4. コンテナの作成・起動

アプリコードを作成

Rubyは本記事の目的から逸れるので割愛。

Dokerfile の作成

Dockerfileはアプリコード,ライブラリ,ベースイメージからイメージを作成する。

FROM ruby:2.7

RUN mkdir /var/www
COPY main.rb /var/www
CMD ["ruby", "/var/www/main.rb"]

Dockerfileからイメージを作成

docker image build -t sample/webrick:latest .

イメージが存在しているか確認する

docker image ls

sample/webrick が存在していればイメージのビルドに成功

イメージからコンテナを作成・起動

ローカルの8000番ポートとDocker の8000番ポートを接続し、sample/webrick:latest イメージからコンテナを作成

docker container run -p 8000:8000 --name webrick sample/webrick:latest

コンテナの起動を確認する

localhost:8000 に接続し、ブラウザにHelloが表示されたら成功

その他 Docker コマンド

現在存在するコンテナを停止・削除

docker container ls -a
docker container stop webrick
docker container rm webrick

ログを見る

docker container logs webrick  

コンテナ内でコマンドを使用する

docker container exec webrick ruby -v

後片付け、現在使用していないコンテナを削除する

docker system prune -a

Dockerfile を作ろう

ここからは上記までと別のリポジトリで行う

まず Gemfile ( Ruby のライブラリ ) を作成

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

gem "sinatra"

ディレクトリトップに Dockerfile を作成

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

CMD ["/bin/bash"]
  1. Rubyのバージョンを指定
  2. ワークディレクトリを指定 (なんでも良い)
  3. ローカルのソースをワークディレクトリにコピー
  4. コンテナ起動時にコンテナ内で bash を起動させるコマンド

Dockerfile からイメージを作成

docker image build -t sample/sinatra:latest .

Docker をインタラクティブモードで起動( -it )、ローカルのsrc内のコードをワークディレクトリと共有する( -v )

docker container run -it -p 4567:4567 -name sinatra -v ${PWD}/src:/var/www

ライブラリをインストールする

bundle config --local set path 'vendor/bundle'
bundle install

アプリソース( app.rb )を作成

require 'sinatra'

configure do
  set :bind, '0.0.0.0'
end

get '/' do
  'hello world!'
end

アプリが実際に動くか確認

bundle exec ruby app.rb

localhost:4567 で hello world! が表示されたら成功

Dockerfile を書き換え

RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

CMD ["buncle", "exec", "ruby", "app.rb"]

コンテナを削除・作成・起動

docker container rm sinatra
docker image build -t sample/sinatra:latest .
docker container run -p 4567:4567 -name sinatra -v ${PWD}/src:/var/www

再度 localhost:4567 で hello world! が表示されたら成功

Docker Compose で Rails を構築

実際のwebサービスは複数のアプリを連携する必要がある。そのためには複数のコンテナを連携・管理する必要がある。

そのために、docker-compose.yml で複数のコンテナを管理する

よく使うコマンド一覧

docker-compose build
docker-compose up -d
docker-compose down
docker-compose ps
docker-compose logs
docker-compose run <サービス> <コマンド>
docker-compose exec <サービス> <コマンド>

全体の流れ

  1. Docker関連のファイルを用意
  2. 初期設定
  3. 起動
  4. 追加操作

Dockerfile を用意

heroku

heroku CLI をインストール ( mac用 )

brew tap heroku/brew && brew install heroku

エラー : Your Command Line Tools are too outdated.

対処法

softwareupdate --all --install --force
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install

brew tap heroku/brew && brew install heroku

成功

コンソールで heroku ログイン

heroku login
heroku container:login

エラー : Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

原因 : 再起動したため Docker が起動されていなかった

対処法 : Docker 起動

heroku container:login

成功

heroku create rails-docker-mk1

DBアドオン追加

heroku addons:create cleardb:ignite -a rails-docker-mk1

DB設定

src>config>database.ymlを書き換える

production:
  <<: *default
  database: <%= ENV['APP_DATABASE'] %>
  username: <%= ENV['APP_DATABASE_USERNAME'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
  host: <%= ENV['APP_DATABASE_HOST'] %>

接続先情報を確認

heroku config -a rails-docker-mk1

確認した接続先情報を Heroku の環境変数に登録

heroku config:add APP_DATABASE='heroku_bc91f1bfa347c49' -a rails-docker-mk1

heroku config:add APP_DATABASE_USERNAME='bb12b1aa39d8c4' -a rails-docker-mk1

heroku config:add APP_DATABASE_PASSWORD='cce1dcc9' -a rails-docker-mk1

heroku config:add APP_DATABASE_HOST='us-cdbr-east-05.cleardb.net' -a rails-docker-mk1

設定が正しく行えているか確認

$ heroku config -a rails-docker-mk1

本番環境に公開

Dockerfile を本番環境用に修正

トップディレクトリに start.sh 作成

Dockerfile に下記を追加

ENV RAILS_ENV=production


COPY start.sh /start.sh
RUN chmod 744 /start.sh
CMD ["sh", "/start.sh"]

start.sh にshellscript追加

if [ "${RAILS_ENV}" = "production" ]
then
    bundle exec rails assets:precompile
fi

bundle exec rails s -p ${PORT:-3000} -b 0.0.0.0
heroku config:add RAILS_SERVE_STATIC_FILES='true' -a rails-docker-mk1

ローカルサーバーが立っていると本番環境と干渉するらしいので閉じる。

docker-compose down
rm src/tmp/pids/server.pid

heroku のタイムアウトの時間を60秒から120秒に変更。(無料の heroku サーバーは性能が低く、初期設定の60秒だとタイムアウトを起こしやすいため)

https://tools.heroku.support/limits/boot_timeout

Dockerイメージをビルド・リリース

heroku container:push web -a rails-docker-mk1
heroku container:release web -a rails-docker-mk1

DBマイグレーション

heroku run bundle exec rake db:migrate RAILS_ENV=production -a rails-docker-mk1

heroku でリリースしたイメージをブラウザで開く

heroku open -a rails-docker-mk1

これでサイトに繋がれば成功

今回は ApplicationErorr が表示された。失敗 ( 未解決 )

この先 CI/CD のため今回の学びたい内容から逸れるためここで一旦終了。