Dockerの基本操作

https://www.youtube.com/watch?v=lZD1MIHwMBY

## Linux


ターミナル：ユーザーがコマンドを入力、実行結果を表示、あくまで画面担当

シェル：仲介役・命令解釈、Linuxに伝える

Linux：受け取った命令を実行する

```ruby
echo "Hell" > tmp # ファイルに追加する
cat tmp # 内容を表示
less tmp # 内容を全画面で表示・ファイルが長い時に使う
```

## 04 Dockerを使ってみよう

イメージ：コンテナに必要なものを記載した雛形

↓ 作成

コンテナ：OSの実行環境

↓ 起動

実行

デーモンにタスクを伝える。

Dockerデーモンはバックグラウンドで起動しており、クライアントから受け取ったコマンド通りに、イメージやコンテナを作成・実行するアプリケーション。デーモンの流れは以下の通り。

1. DockerレジストリからDockerイメージを取得
2. イメージからコンテナを起動
3. コンテナを実行

## 05 Dockerを使ってみる

~/Docker 以下

`main.rb` #アプリケーションコード

```ruby
require "webrick"

server = WEBrick::HTTPServer.new(
	DocumentRoot: './',
	BindAddredd: '0.0.0.0',
	Port: 8000
)
server.mount_proc('/') do |req, res|
	res.body = "hello"
end

server.start
```

`Dockerfile`　こいつがDockerイメージを担う

```ruby
FROM ruby;2.7

RUN /var/www
COPY main.rb /var/www

CMD ["ruby", "/var/www/main.rb"]
```

```ruby
# イメージを作るコマンド、イメージをビルドする
# -tオプション、タグ付け、.(今いるディレクトリ)に対して"sample/webrick:latest"というタグをつける。
# タグ名の構成 名前空間:ver情報
docker image build -t sample/webrick:latest .

# 今存在しているイメージの存在
docker image ls

# dockerのコマンド確認
docker --help

# docker imageのコマンド確認 
docker image --help

# イメージの作成と起動
# -pオプション、ポート指定　ローカルポート:ドッカーポート（今回はこっちは8000番じゃなきゃいけない）
# --name コンテナの名前をつけている。"付けたい名前 対象のイメージ" の順番
docker container run -p 8000:8000 --name webrick sample/webrick:latest
```

```ruby
# コンテナの停止
ctrlC
docker container stop webrick

# コンテナの起動状態の確認
docker container ls
# 停止しているコンテナを含めた起動状態の確認
docker container ls -a

# コンテナの削除
docker container rm webrick
```

```ruby
# "-d" バックグラウンドで実行
docker container run -d -p 8000:8000 --name webrick sample/webrick:latest

# コンテナのログを確認する
docker container logs webrick

# コンテナ内で別のコマンドを実行したい
# "コンテナ名 実行内容"
docker container exec webrick ruby -v

# 現在しようしていないイメージやコンテナを削除する。
docker system prune -a
```

## 06 Dockerfile

ベースのイメージを指定して、ベースイメージに対してコマンドを羅列する。

```ruby
FROM ruby:2.7 # ベースイメージを指定する

WORKDIR /var/www # ワークディレクトリは、この後の作業をどこでやるか指定する。なかった場合は作成される。

COPY ./src /var/www # "./src"というソースコードをdockerのワークディレクトリにコピー

CMD ["/bin/bash"] # 一度dockerコンテナ内に入る。bashはシェルの一種。
```

```ruby
# イメージを作成
docker image build -t sample/sinatra:latest .
# コンテナを作成・起動
# -itオプション、インティラクティブにコマンドを実行する。インティラクティブモード
# -v ボリュームをマウント。ローカル修正 = コンテナも修正される
# 最後にコンテナを作成するイメージ名を起動。
docker container run -it -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest

# sinatraをインストールしたい
# "vendor/bundle"を作成、その下にライブラリを作成。
bundle config --local set path 'vendor/bundle'
```

`app.rb`を./src内に作成

```ruby
require 'sinatra'

configure do
	set :bind, '0.0.0.0' # dockerコンテナ内にバインドしておくことで、ローカルからのどんな通信でも反応するように設定。
end

get '/' do
	"Hello world!!"
end
```

```ruby
# bundle execはgemファイルを使った処理を扱い際の枕詞
bundle exec ruby app.rb
# -> webrickというwebサーバーを立ち上げる。
# 4567でサーバーへアクセス。
```

```ruby
FROM ruby:2.7 

WORKDIR /var/www 

COPY ./src /var/www 

RUN bundle config --local set path "vendor/bundle"
RUN bundle install

# RUN bundle config --local set path "vendor/bundle" \
# && bundle install
# これは同義。

CMD ["bundle", "exec", "ruby", "app.rb"]
```

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

## 07 Docker Compose を用いたRails環境構築

```ruby
# イメージのビルド
docker-compose build
# コンテナの作成・起動
docker-compose up -d
# コンテナの停止・削除
docker-compose down
# コンテナの一覧を表示
docker-compose ps
# コンテナ操作のログを表示
docker-compose lgs
# コンテナを作成してコマンドを実行
docker-compose run "サービス名" "コマンド"
# 起動中のコンテナにコマンドを実行
docker-compose exec "サービス名" "コマンド"
```

`./Dockerfile`

```ruby
FROM ruby:2.7
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | 
apt-key add - \
	&& echo "deb https://dl.yarnpkg.com/debian/ stable main"
	| tee /etc/apt/sources.list.d/yarn.list
	&& apt-get update -qq \
	&& apt-get install -y nodejs yarn # nodejsとyarnをapt-getでinstallしている。上では、nodejsとyarnをインストールするためのアップデート関連をしている。
WORKDIR /app # 作業ディレクトリを設定
COPY ./src /app # 作業ディレクトリへrubyアプリをコピー
RUN bundle config --local set path 'vendor/bundle' \ # ライブラリのインストール先を指定
	&& bundle install # gemfileをインストール
```

`./docker-compose.yml`

```ruby
version: '3'
services:
	db: # dbはmysql
		image: mysql:8.0
		command:
			--default-authentication-plugin=mysql_native_password # mysqlの認証関連
		volumes :
			- ./src/db/mysql_data:/var/lib/mysql # ローカルのボリュームをコンテナに同期
		environment:
			MYSQL_ROOT_PASSWORD: password # 環境変数の設定
	web:
		build: . # 今のディレクトリにあるDockerfileを参照する
		command: bundle exec rails s -p 3000 -b '0.0.0.0' # rails serverを起動。ポートはどこでもおっけい。
		volumes :
			- ./src:/app # ソース共有
		ports:
			- "3000:3000" # ローカルの3000ポートをdocker側の3000ポートに接続
		depends_on:  # 依存関係を示す
			- db  # webはdbに依存している。IPアドレスを指定しなくても、繋いでくれる。
```

`./src/Gemfile`

```ruby
source "https://rubygems.org"

gem "rails", "~> 6.1.0"
```

```ruby
# dockerイメージを作成
docker-comopse run rails new . --force --databese=mysql
# ファイルが変更された場合は、もう一度ビルドする
docker-compose build
```

`config/database.yaml`

```ruby
# docker-compose記載の内容に準じて、接続先情報を変更する。
default: &default
	adapter: mysql2
	encoding: utf8mb4
	pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 ) %>
	username: root
	password: password
	host: db
```

```ruby
docker-compose run web rails db:create
```

### コンテナを起動

これらが終わった後に起動する。

```ruby
docker-compose up
```

### 追加の操作

```ruby
# コンテナを削除
docker-compose down
```

## dockerで本番環境

`./Dockerfile`

```ruby
FROM ruby:2.7

ENV

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | 
apt-key add - \
	&& echo "deb https://dl.yarnpkg.com/debian/ stable main"
	| tee /etc/apt/sources.list.d/yarn.list
	&& apt-get update -qq \
	&& apt-get install -y nodejs yarn # nodejsとyarnをapt-getでinstallしている。上では、nodejsとyarnをインストールするためのアップデート関連をしている。
WORKDIR /app # 作業ディレクトリを設定
COPY ./src /app # 作業ディレクトリへrubyアプリをコピー
RUN bundle config --local set path 'vendor/bundle' \ # ライブラリのインストール先を指定
	&& bundle install # gemfileをインストール

COPY start.sh /start.sh #コピー
RUN chmod 744 /start.sh　#権限を付与
CMD ["sh", "/start.sh"]　#ファイルを実行
```

`start.sh`　一部の条件分岐を追加したい場合。

```ruby
# !/bin/sh
if [ "$(RAILS_ENV)" = "prodction" ]
then 
	bundle exec rails assets:precompile # 本番環境の設定
fi

bundle exec rails s -p $(PORT:-3000] -b 0.0.0.
```