LoginSignup
2
4

企業におけるDockerのお作法

Last updated at Posted at 2023-10-11

なぜDockerを使うのか

  • IaCの文脈ではデファクトスタンダードなDockerを使うことが多い
  • 以下のようなケースが多くあるので使うことを推奨(やるやらないは別として知っておくに越したことはない)
    • 「検証環境で動いたコードが商用環境の端末で動かそうとしたら動かなくなった」といった環境依存関係をなくしたい
    • gitからcloneしたが動かなかったコードをくようにしたものをチームで共有したい

概要確認コマンド

手順

以下の3ステップでDockerを動かせる状態にする

  1. Dockerfileを作る
  2. Docker imageをbuildする
  3. Docker containerをrunする

Untitled 1.png

Docker初学者がやるべきこと3選 - Qiitaより拝借)

Dockerfileを配置するディレクトリ構成例

  • Dockerを導入する上でのファイル配置は以下を参考にすると良い(機械学習のプロジェクトを想定)
    • サンプル:

      my_ml_project/
      │
      ├── data/                 # データセットや中間データを格納
      │   ├── raw/
      │   └── processed/
      │
      ├── model/                # トレーニング済みのモデルやモデルのチェックポイントを格納
      │
      ├── notebooks/            # Jupyter ノートブック
      │
      ├── src/                  # ソースコード
      │   ├── __init__.py
      │   ├── data_preparation/
      │   ├── model_definition/
      │   └── training_scripts/
      │
      ├── tests/                # テストコード
      │
      ├── Dockerfile            # Dockerfile
      │
      ├── requirements.txt      # 必要なPythonパッケージのリスト
      │
      └── README.md             # プロジェクトの説明やセットアップ方法など
      
      

Dockerfileの書き方

  • Dockerfileの作り方は2通りある
    1. 自作する:色々と自分でいじれてコピペして使う時に便利

      • サンプル:

        # 1. ベースイメージ(以下追加する元となるイメージ)を指定(イメージ:バージョン)
        FROM ubuntu:20.04
        
        # 2. あとはベースイメージに追加したい内容を記載する
        # docker imageをbuildする際に自動実行されて、docker runする際にはすでに実行済みの状態となる
        
        # RUNで普段ターミナルで打っているコマンドを記載できる
        RUN apt-get update && apt-get install -y --no-install-recommends \
                # 日本語表示で文字化けを防ぐ
                language-pack-ja-base language-pack-ja \
                libglib2.0-0 \
                libsm6 \
                libxrender1 \
                libxext6 \
                build-essential \
                libssl-dev \
                libffi-dev \
                python3-dev \
                python3 \
                python3-pip && \
            rm -rf /var/lib/apt/lists/*
        
        # 日本語表示で文字化けを防ぐ
        RUN echo 'export LANG=ja_JP.UTF-8' >> ~/.bashrc
        RUN echo 'export LANGUAGE="ja_JP:ja"' >> ~/.bashrc
        
        # source ~/.bashrc と同じ処理
        RUN . ~/.bashrc
        
        # pip install
        RUN pip3 install --upgrade pip setuptools
        COPY ./requirements.txt /tmp
        RUN pip3 install -r /tmp/requirements.txt
        
        # Required for nvidia-docker v1
        RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
            echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf
        
        # PATHの指定
        ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
        ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64
        
        # nvidia-container-runtime
        ENV NVIDIA_VISIBLE_DEVICES all
        ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
        ENV NVIDIA_REQUIRE_CUDA "cuda>=11.0 brand=tesla,driver>=418,driver<419 brand=tesla,driver>=440,driver<441 brand=tesla,driver>=450,driver<451"
        
        
    2. Docker Hubからpullする:cudaのバージョン対応するベースイメージは自作すると大変なのでDocker Hubから探すことが多い

Docker buildコマンド

  • 何度も使う場合があったり、buildしているdocker imageの実行元コマンドを忘れる場合があるのでシェルスクリプトとしてファイルを作成しておくと良い(シェルスクリプトもgitリポジトリに上がると見栄えが悪いのでREADMEなどでサンプルを書く程度にとどめておき、pushされないように.gitignoreに*.shなどと記載しておくと良い)

  • サンプル:

    #!/bin/bash
    # docker build -t [イメージ名]:[タグ] .
    docker build -t my_ml_project:latest .
    
    

    build時のコマンド:

    • [イメージ名] は作成するDockerイメージの名前

    • [タグ] はイメージのバージョンやラベルを示すもので、例えば latest などを指定することが多い

    • . はDockerfileが存在する現在のディレクトリを指す

    • -fオプションを使用する場合

      • プロジェクトのディレクトリ内で、複数のDockerfileがある場合(例: Dockerfile.devDockerfile.prod など)、f オプションを使ってどのDockerfileを使ってビルドするか指定することができる

        #!/bin/bash
        # docker build -f [Dockerfileのパス] -t [イメージ名]:[タグ] [ビルドコンテキストのパス]
        docker build -f path/to/Dockerfile -t my_ml_project:latest .
        
        
        • [Dockerfileのパス]: 使用するDockerfileへのパス。
        • [イメージ名]: 作成するDockerイメージの名前。
        • [タグ]: イメージのバージョンやラベル。
        • [ビルドコンテキストのパス]: Dockerイメージをビルドする際のコンテキスト(通常、Dockerfileがあるディレクトリやその親ディレクトリ)。
    • 作成したイメージは以下のコマンドで確認できる

      docker images
      

Docker runコマンド

  • 何度も使う場合があったり、runしているdocker containerの実行元コマンドを忘れる場合があるのでシェルスクリプトとしてファイルを作成しておくと良い(シェルスクリプトもgitリポジトリに上がると見栄えが悪いのでREADMEなどでサンプルを書く程度にとどめておき、pushされないように.gitignoreに*.shなどと記載しておくと良い)

  • サンプル:

    • シンプルなバージョン

      #!/bin/bash
      # docker run [オプション] [イメージ名]:[タグ] [コマンド] [コマンドの引数...]
      docker run \
          --user root \ # ユーザを指定
          --name sample \ # runして立ち上げるコンテナ名を指定
          -it \ # -i -tオプションをまとめて書く書き方
          # -iはinteractive(対話型)という意味でコンテナ内で実行するシェルと標準出力をつなぐというオプション(このオプションをつけないとコンテナの中のシェルにコマンドを実行してもらうことができない状態になる)
          # -tはtty (端末デバイス)という意味でコンテナ内にコンテナ用の疑似的なターミナルを用意するというオプション(このオプションをつけないとコンテナ内のターミナルでユーザー名やカレントディレクトリも出ていないし、タブによる入力補完なども機能しない状態になる)
          my_ml_project:latest \ # runするコンテナの名前:タグを指定
          /bin/bash # こちらのオプションをつけるとコンテナ内でターミナル操作可能(バックグラウンドでスクリプト実行したい場合はつけなくて良い)
      
      
    • 便利オプションを追加したバージョン

      #!/bin/bash
      # docker run [オプション] [イメージ名]:[タグ] [コマンド] [コマンドの引数...]
      docker run \
          --rm \ # コンテナを停止した際に削除するオプション
            --p 8080:8080 # ポートを指定(ホストポート:コンテナポート) \
          --user root \ # ユーザを指定
          --gpus all \ # 使用するGPU群を指定
          --name sample \ # runして立ち上げるコンテナ名を指定
          -it \ # -i -tオプションをまとめて書く書き方
              # -iはinteractive(対話型)という意味でコンテナ内で実行するシェルと標準出力をつなぐというオプション(このオプションをつけないとコンテナの中のシェルにコマンドを実行してもらうことができない状態になる)
              # -tはtty (端末デバイス)という意味でコンテナ内にコンテナ用の疑似的なターミナルを用意するというオプション(このオプションをつけないとコンテナ内のターミナルでユーザー名やカレントディレクトリも出ていないし、タブによる入力補完なども機能しない状態になる)
          -v /workspace/:/workspace/ \ # ボリュームマウント(ホストPCとコンテナで共有したいディレクトをフルパスで記載)
          -w /workspace/src/ \ # コンテナのターミナルを開く際、初期位置となるディレクトリをコンテナの方のフルパスで指定
          my_ml_project:latest \ # runするコンテナの名前:タグを指定
          /bin/bash # こちらのオプションをつけるとコンテナ内でターミナル操作可能(バックグラウンドでスクリプト実行したい場合はつけなくて良い)
      
      

    run時のコマンド:

    • [イメージ名]: 実行したいDockerイメージの名前。
    • [タグ]: イメージのバージョンやラベル。指定しない場合、デフォルトで latest タグが使用されます。
    • [コマンド] および [コマンドの引数...]: イメージ内で実行するコマンドとその引数。これを省略すると、Dockerfileの CMD 命令で指定されたコマンドが実行されます。

    一般的なオプション:

    • -d: デタッチモード。コンテナをバックグラウンドで実行します。
    • --name [コンテナ名]: コンテナに名前を付けます。
    • -p [ホストのポート]:[コンテナのポート]: ポートマッピング。ホストとコンテナのポートをマッピングします。
    • -v [ホストのディレクトリ]:[コンテナのディレクトリ]: ボリュームマッピング。ホストとコンテナのディレクトリをマッピングします。
    • -e [変数名]=[値]**: 環境変数をセットします。
    • --rm: コンテナが停止した後に自動的に削除します。

その他

  • その他
    • Docker Desktop有償化について:
      • Win, MacでDockerを使おうとする場合、Docker Desktopが必要となり、従業員250以上で年間売り上げ1000万ドル以上の組織で商用利用するケースに該当するので有償化する必要があるので注意
      • vscodeの拡張機能 remote containerを使いmacからlinuxマシンにリモート接続する場合もおそらくDocker Desktopが必要になる
      • しかし以下のケースではDocker DesktopなしにDockerが使用できるので問題ない
        • WSL経由でdockerを利用する場合
        • linuxマシンでdockerを利用する場合

参考

2
4
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
2
4