プログラミングスクールでDockerを使用した経験はありましたが、しばらく使っていなかったので結構忘れていましたので、復習しました。
dockerコマンド
-
ログインする
docker login -
イメージを削除する
docker rmi -
imageに名前をつける
docker tag IMAGE_ID IMAGE_NAME:TAG -
docker hubからイメージをpull
docker pull -
docker hubにイメージをpush
docker push
bundle できていない場合は、
- docker-compose down/ docker-compose build/ docker-compose up
でdownし直してから、再度buildとupをする
もしくは、以下のコマンドを実行後、バックエンドのコンテナに入り、bundle install
を実行でも良い。
- コンテナの再起動ポリシーを上書きし、コンテナの実行後に削除
docker-compose run --rm image bash
※イメージの名前とレポジトリの名前は一致する必要があるので、dockerhubにpushする際は、その点に注意する。※以下の名前の変更コマンドで、変更してからpushする。docker tag
-
コンテナ作成+スタート
docker run
#run = create + start -
プロセスを表示
docker ps -a -
コンテナに入る
docker run -it ubuntu bash
-i: インプット可能 -t: 表示を綺麗にする -
containerを止める
docker stop container -
停止したコンテナをup状態にする。まだ、containerには入っていない。
docker restart container -
コンテナに入る
docker exec -it container bash -
コンテナに名前をつける
docker run —name ubuntu
コンテナに名前をつける目的は、以下の3点。
- 起動させ続けるコンテナを立てるとき
- 共有サーバを使うとき
- 他のプログラムで使用するとき
-
containerを削除する
docker rm container -
containerを全削除する
docker system prune -
detached mode コンテナを起動後にdetachする(バックグラウンドで動かす)
docker run -d -
foreground modeコンテナをexit後に削除する(1回きりのコンテナ)
docker run —rm
docker imageを更新する方法
1、containerからdocker imageを作成
- docker commit container
xxx ~ % docker commit 98hogehogeohe ubuntu:updated
#:でタグ付けしている
sha256:7hogehogeohoegoeohehoehoeogeohoeoheoohogeoheg644d7ab3c8690e8147e6
xxx ~ % docker images
#imageが2個できていることを確認。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu updated 76sgsgasdgsd 18 seconds ago 77.8MB
ubuntu latest d2hogehogeho 11 months ago 77.8MB
2、docker fileからdocker imageを作成
一般的には1よりも、docker fileからimageを作成する方が多い。
Dockerファイル
Docker imageの設計図で、DockerファイルからDocker imageを作成する。
・Dockerファイルがあるディレクトリに移動して、以下のコマンドでイメージを作成
docker build .
・出来立てほやほやのイメージ(TAG がNONE)はdangling image
docker images -f dangling=true
#で検索できる。
-
FROM
ベースとなるイメージを決定
DockerファイルはFROMから始める
基本的には、OSを指定する=>ubuntuやalpine
alpineは5MBなので軽量で使用可能 -
RUN
Linuxコマンドを実行
RUNを使うことで好きなようにカスタマイズ
RUN毎にLayerが作られる -
CMD
コマンドのデフォルトのコマンド
CMD[“executable”, “param1”, ”param2”] 例えば、[“/bin/bash“]みたいな感じ。
原則Dockerファイルの最後に記述
Layerは作らない
CMDとENTRYPOINTは似ているので注意!
Ubuntuではapt-get(または、apt)というコマンドでパッケージ管理をする。
- apt-get update:
新しいパッケージリストを取得 - apt-get install
パッケージをインストール
ベストプラクティス:Docker imageのLayer数は最小限にする!
Layerを作るのはRUN, COPY, ADDの3つ対応は以下の2点
- コマンドを &&でつなげる
- バックスラッシュで改行する
作成している途中はchacheを利用するために、RUNを追加してbuildする。
最後にうまくいくことを確認したら、RUNを一つにまとめる。
dockerファイルを指定するのではなく、current directoryを指定するのか?
=> なぜなら、そのディレクトリをbuild contextとして利用できるから!!
dockerでは、buildされるとdocker daemonに渡される。
基本的にbuildに使わないファイルはbuild contextに入れない。
もし、利用したいファイルがある場合は、ADDやCOPYでbuild contextの中にあるファイルをimageに持っていける。
COPY
COPY <src> <destination>
これを使えば、build contextに置いたファイルなどをcontainerに持っていける。
ADD
COPYと同じようなことができる。
じゃあ、COPYとADDの違いはなんなの?
- COPY
単純にファイルやフォルダをコピーする場合 - ADD
tarの圧縮ファイルをコピーして解凍したい場合
Dockerファイルという名前のファイルがビルドコンテキストに入っていない場合
以下のように実行すると、ビルドコンテキスト以外を指定できる。
docker build -f <docker file name><build context>
# パスでも指定可能
docker build -f ../Dockerfile.dev
ENV:環境変数を設定する
ENV <key> <value>
ENV <key>=<value>
環境変数の一覧を表示
$ env
WORKDIR
Docker instructionの実行ディレクトリを変更する。
RUNはルート直下で実行されるため、例えば、
RUN mkdir sample_folder
RUN cd sample_folder
RUN touch sample_file
のように記述してもsampleフォルダの中にファイルは作成されない。
じゃあ、どうやってフォルダの中にファイルを作成するのか?
結論、WORKDIRを使う。
FROM ubuntu:latest
RUN mkdir sample_folder
#絶対パスで指定する
WORKDIR /sample_folder
RUN touch sample_file
- WORKDIRを使用する場合は、勝手にフォルダを作ってくれるのでRUN mkdirする必要はない。
ファイルシステムをコンテナにマウントする(超重要な気がする)
-v host:container
コンテナに実際にホストのファイルシステムがあるかのように振る舞う。
コードはホストに置いておいて、実行環境や解析環境としてcontainerを使う。
ユーザーIDとグループIDを指定してコンテナをrunする
created_in_Dockerfileに書き込みしようとするとpermission denyされる。
ls -la で権限を確認すると以下のようになっている。
Dockerimageをtarファイルに圧縮
docker save myimage > mydocker.tar
ssh -i mydocker.pem ubuntu@<hostname>
# tarファイルをDockerimageに変換
docker load < mydocker.tar
docker run -it myimage bash
ec2のpemkeyを使用してsftp
sftp -i mydocker.pem ubuntu@<hostname>
#ec2にデータを転送する
put local/path
# ec2からデータを受信する
get remote/path
docker-compose
dockerコマンドでコンテナを起動するときに、オプションを指定する。
例えば、-it / -v / -p などいくつかある。
それを毎回記述していたら長すぎて面倒なので、事前にその設定をしてdocker-composeコマンドを使って楽にしようというもの。
また、もう一つの理由としてはdockerコンテナを複数利用したい場合なんかに使うらしい。
docker-composeコマンド
-
docker-compose.ymlを元にコンテナ群を作成し起動
docker-compose up -
Dockerイメージのビルド
–build -
Dockerコンテナをバックグラウンドで起動
-d
* コンテナを停止
docker-compose stop
* コンテナを削除
docker-compose rm -f
-
docker-compose.ymlを元にコンテナ群を停止して削除
docker-compose down -
Dockerコンテナの再起動
docker-compose restart -
Dockerコンテナが起動しているか確認
docker-compose ps -
コンテナでコマンド実行コマンド
docker-compose run [コンテナ名] [コンテナで実行したいコマンド]
docker-compose exec [コンテナ名] [コンテナで実行したいコマンド] -
Gemfileに記述したGemをインストール
docker-compose build
run と execの違い
run
- コンテナを新しく作って実行する。
- 「docker-compose up」等でコンテナが起動していなくても使える。
- 新しいコンテナに接続するのでコマンド履歴が残らない。
- 低速用途コンソール用のコンテナ等、普段は立ち上げもしないが、いざコマンド作業の際にのみ使うコンテナで作業をする場合はこれを使う。
exec
- docker-compose up などで起動しているコンテナを利用する。
- 起動中の docker コンテナがないと実行できない。
- 同じコンテナに接続するのでコマンド履歴が残っている。
- 高速用途DBコンテナ等、普段から当たり前に立ち上げているコンテナに接続する場合はこちらを使う。
RAILSの環境を構築
version: '3'
volumes:
db-data:
services:
web:
build: .
ports:
- 3000:3000
volumes:
- ".:/product-register"
environment:
- "DATABASE_PASSWORD=postgres"
tty: true
stdin_open: true
depends_on:
- db
links:
- db
db:
image: postgres
volumes:
- "db-data:/var/lib/postgresql/data"
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=postgres'
dockerfile
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
build-essential\
libpq-dev\
nodejs\
postgresql-client\
yarn
WORKDIR /product-register
COPY Gemfile Gemfile.lock /product-register/
RUN bundle install
Railsプロジェクトの作成
docker-compose run web rails new . --force --no-deps --database=postgresql
docker-compose build
DB接続設定
default: &default
adapter: postgresql
encoding: utf8
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: db
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
development:
<<: *default
database: app_development
test:
<<: *default
database: app_test
.
.
.
DB作成
docker-compose run web rails db:create
イメージの起動
docker-compose up
http://localhost:3000/ にアクセスしてページが表示されたら成功です。
ちなみに、localではdocker-compose.ymlのportsの3000:3000の左側を使用するため、こちらを違うポートにしている場合はそちらのポートを使用する。右側はdockerのポートとなる。