Docker基礎知識 docker/docker file/docker-compose/rails

dockerコマンド

・ログインする

docker login

・イメージを削除する

docker rmi <image>

imageに名前をつける

docker tag IMAGE_ID IMAGE_NAME:TAG

・docker hubからイメージをpull

docker pull <image>

・docker hubにイメージをpush

docker push <image>

※イメージの名前とレポジトリの名前は一致する必要があるので、dockerhubにpushする際は、その点に注意する。
※以下の名前の変更コマンドで、変更してからpushする。
docker tag <source><target>

・コンテナ作成+スタート

docker run <image> 

# 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 <name> ubuntu

コンテナに名前をつける目的は、以下の3点。

 1. 起動させ続けるコンテナを立てるとき
 2. 共有サーバを使うとき
 3. 他のプログラムで使用するとき

・containerを削除する

docker rm <container>

・containerを全削除する

docker system prune

detached mode 
コンテナを起動後にdetachする(バックグラウンドで動かす)

docker run -d <image>

・foreground mode
コンテナをexit後に削除する(1回きりのコンテナ)

docker run —rm <image>

detach: ctrl+p+q   /  docker stop <container>
detachをすると元のstatusが残る。up状態のまま。
docker attach <container> 残ったプロセスに入る。

docker imageを更新する方法


1、containerからdocker imageを作成

docker commit <container> <new image>
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を作成

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 <package>: <package>をインストール

ベストプラクティス:Docker imageのLayer数は最小限にする!
Layerを作るのはRUN, COPY, ADDの3つ

対応は以下の2点
・コマンドを &&でつなげる
・バックスラッシュで開業する

作成している途中はchacheを利用するために、RUNを追加してbuildする。
最後にうまくいくことを確認したら、RUNを一つにまとめる。

dockerファイルを指定するのではなく、current directoryを指定するのか?
=> なぜなら、そのディレクトリをbuild contextとして利用できるから!!

build contextとは?

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 で権限を確認すると以下のようになっている。

ホストのポートをコンテナのポートにつなげる
コンテナがアクセスできる上限のCPUとメモリを設定


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 [コンテナ名] [コンテナで実行したいコマンド]

run と execの違い

・run
コンテナを新しく作って実行する。
「docker-compose up」等でコンテナが起動していなくても使える。
新しいコンテナに接続するのでコマンド履歴が残らない。
低速

用途
コンソール用のコンテナ等、普段は立ち上げもしないがいざコマンド作業の際にのみ使うコンテナで作業をする場合はこれを使う。

・exec
docker-compose up などで起動しているコンテナを利用する。
起動中の docker コンテナがないと実行できない。
同じコンテナに接続するのでコマンド履歴が残っている。
高速

用途
DBコンテナ等、普段から当たり前に立ち上げているコンテナに接続する場合はこちらを使う。

プログラミングマガジン

・Gemfileに記述したGemをインストール

docker-compose build


RAILSの環境を構築

docker-compose.yml

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


この記事が気に入ったらサポートをしてみませんか?