LoginSignup
0
0

More than 1 year has passed since last update.

個人的リマインド用

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

Dockerって何?

アプリを簡単に開発・デプロイできる仕組みのこと。
OS、ライブラリ、アプリケーションをひとまとめにして、配布できる。さらにテスト環境だけでなく、本番環境でも使える。

環境構築 for mac

今回必用なもの
iTerm2,VSCode,Docker,Gitそれぞれ動画に従いインストール

Dockerを使ってみよう

docker run hello-world

何が起こっているか
イメージからコンテナを作成し、起動させている。
イメージ: コンテナに必用なものを記載した雛形
コンテナ: Dockerの実行環境

クライアント(依頼主)がdocker runというコマンドをデーモンに対して伝える

デーモンはバックグラウンドで起動していてクライアントの命令通りに、イメージやコンテナを操作するアプリケーションのこと

今回、デーモンはhello worldという命令を受け取ったら、レジストリ(オンライン上で保存しておく場所)からhello worldのイメージをとってくる

その後デーモンは、とってきたイメージをもとにコンテナを作成し、起動させて結果としてhello worldが表示される

アプリを実行・作成しよう

今回はRubyでWebサーバーを用意し、トップページにアクセスされたらhelloと返す
基本的な流れ
1.アプリコードとDockerfileを用意
2.そこからDockerのイメージを作成
3.イメージからコンテナを作成し起動

イメージを作る下準備

まずmain.rbというファイルを用意し、webサーバーを用意しhelloと表示するコードを書く(アプリケーションコード)

続いてDockerfile(イメージの雛形)を用意。Dockerfileにはアプリコードやライブラリ、ベースイメージに関することが記載される。
※Dockerfile例

FROM ruby:2.7
#Rubyの2.7を使う

RUN mkdir /var/www
#RUNはコマンドの実行。以下のディレクトリを作れという意味
COPY main.rb /var/www
#さっき作ったmain.rbを/var/wwwの下に置く

CMD ["ruby", "/var/www/main.rb"]
#Dockerのイメージを起動した時に実行するコマンドを指定している。rubyでmain.rbを実行

これでイメージを作る下準備ができた

イメージを作る

docker image build -t sample/webrick:latest .

-t → 今後使いやすくするためにタグをつける
. → 今いるディレクトリのDockerファイルを参照する

イメージが作れたか確認するコマンド

docker image ls (今回はsample/webrickがある)

コマンド確認

docker --help
docker image --help

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

docker container run

(今回)
docker container run -d -p 8000:8000 --name webrick sample/webrick:latest

-d → バックグラウンドで実行できる。ターミナルが使えるように
-p → ポートの指定。左側が自分のポートで、右側がDockerのポート。今回は自分の8000番ポートをDockerの8000番ポートに接続させる。
--name → 名前をつけておくと後々楽(今回はwebrick)
最後に指定のイメージ

コンテナのライフサイクル
作成→起動→停止→削除

コンテナが今どうなっているかの確認

docker container ls (起動中のコンテナ確認)
docker container ls -a (停止中のコンテナも含め確認)

コンテナの停止と削除

停止

Ctrl + C or
docker container stop webrick(コンテナ名)

削除
停止後に

docker container rm webrick(コンテナ名)

コンテナ操作でよく使うコマンド

異常が起きた時にログを見て分析する

docker container logs webrick(コンテナ名)

実行中のコンテナで別のコマンドを実行したい時

docker container exec webrick(コンテナ名) ruby -v

使わないイメージやコンテナが溜まってハードディスクを圧迫するので後片付けしたい時

docker system prune -a(all)

Dockerfileを作ろう

Dockerfile振り返り
アプリケーションやライブラリ、ベースイメージなどの情報を書き込み、これを基にイメージを作成する

今回の前提
Dockerというディレクトリで作業し、この中にはsrcディレクトリ、さらにその中にはGemfileがある。目標はsinatraを動かすこと。

docker/src/Gemfile

・
・
gem "sinatra"

srcと同じ階層にDockerfileを作成

Docker/src/Dockerfile

FROM ruby:2.7
#rubyというイメージの2.7を指定

WORKDIR /var/www
#ディレクトリは何でもいい。作業をする場所。ディレクトリがない場合は作ってくれる

COPY ./src /var/www
#srcディレクトリ以下のファイルを/var/wwwの下にコピー。アプリケーションコードをDockerにコピーできる

CMD ["/bin/bash"]
#Docker起動時にbashを開く

Dockerfileを作ったので次はイメージを作成

docker image build -t sample/sinatra:latest .

コンテナを作成し起動

docker container run -it -p 4567:4567(sinatraのポート番号) --name sinatra 
-v ${PWD}/src:/var/www sample/sinatra:latest

-it → Dockerにインタラクティブモード(対話型)でコンテナを起動させることを明示。shellを起動する際にいる
-v → ボリュームのオプション。コロンから左が自分、右がDocker側。自分のディレクトリのsrc以下をDocker内の/www以下に共有する。これをしないと更新した時に、イメージを作り直さないといけない。

上のコマンドを実行するとbashが開く。自分がいる場所は/var/wwwだが、ローカルの変更内容が共有されていることがわかる。

ライブラリのインストール

手法(開発プロセス):
一度Dockerのコンテナ内に入ってコマンドを実行し、うまくいったらそれをDockerfileに反映させる。

現在はbashが開いている

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

vendor/bundleにライブラリの中身をインストールしてという意味

bundle install

Gemfileの中身がインストールされる

Hello worldを表示

app.rbというファイルを作り、そこにHello worldを表示するコードを記述

その後ターミナルで

bundle exec ruby app.rb

Gemfileを使った処理を動かす時はbundle execをつける。
WebrickというWebサーバーが立ち上がる。localhost:4567にアクセスするとHello worldが記述されている。

続いてこれをDockerfileに反映させる

Docker/src/Dockerfile

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

RUN bundle config --lcoal set path 'vendor/bundle'
RUN bundle install
#先ほど手動でやったことと同じことが実行される

#1行で書く方法
RUN bundle config --lcoal set path 'vendor/bundle' \
  && bundle install

CMD ["bundle", "exec", "ruby", "app.rb"]
#書き換え。コンテナ起動時にbundle exec ruby app.rbが実行される。スペース区切りをコンマで区切る

Docker Compose

Railsの開発環境を構築

Docker Compose
複数のアプリケーションをまとめて操作
Docker Compose例:

docker-compose.yml

version: '3'
services:
  db: #それぞれ設定
   image: mysql8.0
  web: #それぞれ設定
   build:
   depend_on:
     - db

基本操作

イメージのビルド
docker-compose build
コンテナの作成と起動
docker-compose up -d(バックグラウンドで実行)
コンテナを停止・削除
docker-compose down

その他のよく使う操作(1)

コンテナの一覧を表示
docker-compose ps
ログを表示
docker-compose logs

その他のよく使う操作(2)

コンテナを作成してコマンドを実行(1からコンテナを作成し実行)
docker-compose run <サービス> <コマンド>
起動中にコンテナにコマンド実行(今あるコンテナに実行)
docker-compose exec <サービス> <コマンド>

開発

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

Dockerfile

コードを大まかに(詳しくは動画を確認)

FROM ruby:2.7
RUN ・・・
#今回必用なライブラリを指定(今回はnode.jsとかyarnとか)
WORKDIR /app
COPY ./src /app
#ローカルのソース(Railsのソースコード)を/appにコピー
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install
#Ruby関連のライブラリのインストール

Gemfile

gem 'rails', '~> 6.1.0'

Docker-compose.yml

version: '3'
services: #2つのサービスを定義
  db: #今回はMYSQL
   image: mysql8.0
   command: #MYSQLの認証形式に関する設定
   ---default-authentication-plugin=mysql_native_password
   volumes: #コロンから左がローカルのディレクトリ、右がDockerのディレクトリ ディレクトリを同期
     - ./src/db/mysql_data:/var/lib/mysql
   environment: #環境変数の設定(パスワードの設定)
     MYSQL_ROOT_PASSWORD: password
  web: #今回はRails
   build: . #ベースのイメージとして同じディレクトリにあるDockerfileを参照する
   command: build exec rails s -p 3000 -b '0.0.0.0'
   #railsのサーバーを起動する
   volumes: #同期の設定
     - ./src/app
   ports:
     - "3000:3000"
   depends_on: #依存関係(webがdbに依存。接続先のホスト欄をIPアドレスではなくdbと省略できる)
     - db

初期設定

docker-compose run web rails new . --force --database=myspl(データベースを指定)

コマンドを実行すると新しいGemfile(+他のRailsのファイル)ができている。
Gemfileが更新されたり、Dockerfileの内容が更新された時は、イメージをbuildする

docker-compose build

次はデータベースの設定
src/config/database.yml

初期状態:
default: &default
  ・
  password:
  host: localhost
  ・
書き換え後:
default: &default
  ・
  password: password (docker-compose.ymlのenvironmentのとこ)
  host: db (docker-compose.ymlのdepends_onのとこ)
  ・

続いてデータベースの作成

docker-compose run web rails db:create

起動

docker-compose up

localhost:3000にアクセスでrailsの画面が出る

追加の操作

サーバーの止め方

Ctrl + C or
docker-compose down (いっぺんに停止)

再度起動

docker-compose up -d (バックグラウンドで実行)

コンテナの一覧を表示

docker-compose ps

ログを見る

docker-compose logs

コンテナ内でコマンドを実行したい時(例: bash)

docker-compose exec web /bin/bash (bashが起動しコンテナの中に入れる)

GemfileやDockerfileの修正を反映させたい時

docker-compose build (イメージを作り直す)
docker-compose up -d (もう一度コンテナを作成・起動)

本番環境に公開しよう

本番環境で使わないと、手動でライブラリを入れないといけない。面倒だし、本番とローカルの差異が発生する。

今回はHerokuを使い、Heroku上でDockerコンテナを起動することで本番に公開する。

全体の流れ
1.事前準備
2.Herokuにログイン
3.Herokuアプリを作成
4.DBを追加・設定
5.Dockerfileを本番環境用に修正
6.Dockerイメージをビルド・リリース
7.機能追加

事前準備

githubの登録 + ユーザー名とメールアドレスを設定
Herokuの会員登録 + Heroku CLIインストール

Herokuにログイン

適宜確認

Herokuアプリの作成

リリースしたいものをアプリという単位で管理している

DBの追加・設定

DBの追加

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

DBの設定
本番環境のデータベースの接続先等を変更する(環境変数を使う)

Dockerfileを本番環境用に修正する

処理が本番とローカルでちょっと変わってくる

トップディレクトリにstart.shというファイルを作成。ここに本番環境特有の処理を入れておく。

修正内容
環境変数を設定

FROM ruby:2.7

ENV RAILS_ENV=production ←ここ

一番下にいくつか処理を追加

・
・
COPY start.sh /start.sh
#さっき作ったファイルをDocker側ルートディレクトリ直下にコピー
RUN chmod 744 /start.sh
#実行権限を与える
CMD ["sh", "/start.sh"]
#起動直後にファイルを実行

start.shに処理を記述

/start.sh

#!/bin/sh シェルスクリプトのファイルなのでおまじない的に書く

if [ "${RAILS_ENV}" = "production" ]
then
    bundle exec rails assets:precompile
fi
#Dockerfileはif文が使いにくいのでこっちのファイルで実行している
#Railsは本番環境でコンパイルしなければならないので上記のコードを書く

bundle exec rails s -p ${PORT:-3000} -b 0.0.0.0
#Railsサーバーを起動する。ポートがあればそれを使い、なければどこからのIPアドレスでもOK

その後に環境変数の追加コードを書く。
ちなみにローカルでサーバーが起動している、Herokuで起動しない可能性があるので、docker-compose downでサーバーを削除しておく。

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

Dockerイメージをビルドして、コンテナレジストリの方にpushする

heroku container:push web -a rails-docker-kyt

コンテナレジストリからHerokuの方にリリースする

heroku container:release web -a rails-docker-kyt

DBのマイグレーション(テーブルを更新したい時)

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

機能追加

今はページがないのでサイトに警告が表示されているので作る。
まずは開発するようにサーバーを立ち上げる。

docker-compose up -d

次にコントローラを作る

docker-compose exec web bundle exec rails g controller users

ルーティングの設定

routes.rb

  get '/', to: 'users#index'

コントローラの記述

users_controller

  def index
  end

ビューを作成

users/index.html.erb

<h1>Hello world</h1>

ローカルで作成が完了したので、Herokuに反映させる。ローカルサーバーは落としておく。

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

問題点:
修正とかエラーがあるたびに、pushからやり直すのが鬼のように面倒臭い。そこでCI/CDでテストやデプロイを自動化する。

CI/CD

現在の問題点。手動デプロイがかなり面倒臭い。

用語説明
CI(継続的インテグレーション):
コードが変更されるたびに、ビルドやテストを自動で実行する。
CD(継続的デリバリー):
変更に対しレビューをして、マージされたら自動でデプロイする。

CI/CD構築サービス
CircleCI:
ビルド・テスト・デプロイをクラウド上で行ってくれるCI/CDツール。

全体像
ローカルからGitHubにコードがアップされるたびに、自動でビルドとテストを行う。

テストを終え、レビューしコードがマージされたら、自動でdockerコンテナをデプロイする。

全体の流れ
1.GitHub
2.CI
3.CD

GitHub

・GitHub上でリポジトリ作成
・Gitでコードを管理
・.gitignoreを追加
・コミット、プッシュ

.gitignoreを追加
.gitignoreとはバージョン管理する必要のないものを管理下から外せる。データベースの接続先情報などの機密情報やインストールしたライブラリのコードなどのバージョンを管理する必要のないものを指定しておく。.gitignoreファイルはRailsがデフォルトで用意してくれているがプロジェクトの直下に置かなければならないので、以下のコードを実行。

mv src/.gitignore .
mv src/.gitattributes .

またsrc直下に.gitファイルがあると二重管理になりエラーが起こるので削除しておく。

rm -rf src/.git/

次に.gitignoreファイルを修正。srcの直下に移動したので、全ての文頭にsrcをつけていく。
またMYSQLのデータも管理する必要がないので追加しておく

例:
.bundle
↓
src/.bundle

src/db/mysql_data

CI

GitHubにプッシュされたタイミングで、毎回テストが入るようにCIを構築する。
・テストコードを記載
・CircleCIに登録
・プロジェクトを登録
・configを設定
・環境変数を設定
・GitHubにプッシュ
・テストを修正

テストコードを記載
users_controller_test.rbに落ちるテストを記載

docker-compose up -d
docker-compose exec web bundle exec rake test

結果はred

CircleCIに登録
GitHubでログイン

プロジェクトを登録
Projectsのページにある、現在のアプリのリポジトリからSer Up Projectをクリック。その後、Add Configをクリック。
※CircleCIに関して、.circleci/config.ymlの中に設定を書き込むことで動作する。これがないと動かない。

configの設定
直下に.circleciディレクトリ、その下にconfig.ymlファイルを作成。

.circleci/config.yml

詳細なコードに関しては動画を参照
・バージョンを設定
・orbs: jobを事前に定義しシェアできる。便利な記法がjobのところで使える
・jobsでbuildとtestを定義(詳細は動画で要確認)
・workflowsのところで、何を行うか(今回はbuildとtest)、どっちを先にするかなどを記載

環境変数を設定
master.keyがRailsを動かす際に必要だが、.gitignoreに指定されている。流出してはいけないので、それ自体はいいことだが、ソースコードを動かす上ではこの値が必要なので環境変数として指定しておく。

heroku config:add RAILS_MASTER_KEY='(ここに値を貼り付け)' -a rails-docker-kyt

GitHubにプッシュ
add、コミット、プッシュまで(プルリクの流れが説明されてるので、後で見返す)
予想通りテストは落ちている

テストを修正
assert falseをtrueに。これでgreenになる。

CD

mergeされたら自動でHerokuにデプロイされる

流れ
・configを修正
・環境変数を設定
・Viewファイルを修正
・GitHubにプッシュ
・マージ、デプロイ

configを修正

.circleci/config.yml

詳細は動画を確認
・orbsにheroku: circleci/heroku@1.2.3を追記(後々便利な記法が使えるように)
・jobsに以下を追記
- deploy:
    requires:
      - test
      filters:
        branches:
          only: main
(deployのjobはmainブランチに変更があった時のみ実行)
・deployのjobを定義(詳細は動画を確認)

環境変数の設定
CircleCI上で設定する
Projects→現在のリポジトリ→Project Settings→Environment Variables
→Add Environment Variable→NameとValueを設定
(今回は名前やAPIキー)

Viewファイルを修正
deployされたことがわかるように書き換え

GitHubにプッシュ

マージ、デプロイ

0
0
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
0
0