Docker
[Docker] Dockerについて学ぶ
Dockerとは何か? AWS の定義を借りると、Dockerはアプリケーションを迅速に構築、テスト、デプロイできるソフトウェアプラットフォームです。 Dockerは、コンテナという概念を使用して、従来の重いオペレーティングシステムや仮想マシンで動作するアプリケーションを軽量化し、様々な問題を解決しています。 最近では、Dockerがローカルだけでなく、さまざまなクラウド環境でも活用されています。 例えば、AWSでもDockerイメージを用いてデプロイが可能であり、Github ActionsでもDockerをインストールしてデプロイの自動化、簡単なデプロイ作業を行うことができます。 Dockerはどのような問題を解決するのか? 開発環境を構築する際に自身の開発環境を整えると、多くの問題に直面します。 私は以前のプロジェクトで、あるチームメンバーがPythonでMaria DBを使用するためにmysqlclientというモジュールをインストールする過程でエラーが発生し、トラブルシューティングを行う過程でPythonという言語がバージョンに非常に敏感であることを知りました。 プロジェクトの開始時はPython 3.8バージョンが登場した頃で、彼はエラーが発生した時点ではPython 3.10を使用していました。 実際にはmysqlclientモジュールはPython 3.9までしか対応しておらず、彼のPythonは3.10バージョンでした。 このような問題は、Pythonという特定の言語環境でのみ発生するわけではありません。 特にOSが異なる場合、OSのバージョンが異なる場合にはこのような状況が頻繁に発生することがあります。例えば、以下のようなことが起こるかもしれません。 Windows開発者はVSのCを使用します。 Linux開発者はgccコンパイラを使用します。 #include<stdio.h> #include<stdlib.h> int add(int num,...) { int a, b, anw=0; int* point=NULL; point=&num+1; for(a=0;a<=num;a++) { anw+=point[a]; } return anw; } VSでは上記の関数は単純に最初の引数numを活用し、その後に続くパラメータを可変引数のように使用してパラメータをすべて加算する関数ですが、
2022年7月11日
[Docker] Dockerを始める create, exec, start, run, commit
Docker開始これからDockerの概念を一つずつ確認しながらDockerを始めてみよう Dockerインストール リンク を辿って、自分のOSに合ったDockerをインストールしよう Dockerイメージを取得 Dockerを実行するために、Docker Hubで提供される多くのイメージを使用してみることができる。試しにPythonイメージを見てみよう ▲ Docker Hubでpythonを検索した様子 ターミナルを開き、docker pull pythonと入力すると、最新のPythonイメージを取得することができる。 もし自分のサービスが特定のバージョンのPythonを要求する場合、タグを見つけて特定のバージョンのPythonをインストールすることもできる。 例) docker pull python:3.8.13 Dockerコンテナの状態以下のコマンドを知るためには、Dockerコンテナの状態を理解する必要がある。 Dockerコンテナは一般的なプロセスと同様に、様々な状態値を持つ。 各状態値についての説明は以下の通り。 1. Created コンテナが生成された後、一度も使用されていない場合、この状態が割り当てられる。 Host OSのCPUやメモリを消費しない。 2. Running 文字通りコンテナが実行中の状態を意味する。 この状態はコンテナ内のプロセスが環境(Host OS)とは独立して実行中であることを意味する。 3. Restarting この状態も文字通り、コンテナが再起動中であることを意味する。 docker runコマンドでオプション--restart=[RESTART_POLICY]を使用して、再起動時のアクションを定義できる。 RESTART_POLICY no: 再起動しない(default) on-failure: コンテナが正常終了(0コードで終了)でない場合再起動 always: プロセス終了時に常に再起動 unless-stopped: 明示的に停止されるか、Docker自体が停止、または再起動されない限りコンテナを再起動する。 4. Exited 内部プロセスが終了した時、この状態に変更される。Created状態と同様にCPU、メモリを消費しない。
2022年7月12日
[Docker] Docker Storageについて知ろう: Volume vs Bind Mount
Docker Storage今回はDocker Storageについて説明します。 Storageはその名の通り単純に保存領域を意味しますが、コンテナを使用する場合、従来のものよりやや複雑に感じるかもしれません。 これは開発においてStorageが非常に重要な部分であり、多くの人がコンテナベースの開発環境よりもHost OSベースのlocal開発環境を採用する理由でもあります。 一部の人は実際のデプロイサーバーでだけdockerizeするのが良いと言いますが、私はlocal開発環境にもDockerを適用した方がその真価を見られると考えます。 上記はDockerで使用するStorageを図で説明したものです。 Bind Mountbind mountはHost OSのファイルシステム(以下FS)と、ContainerのFSをlinkingすることで、コンテナ内部にあたかもHost OSのファイルがあるかのように動作させることができます。 実際にはそのように動作し、Linuxコマンドのlnコマンドに似ていると言えるでしょう。 このコマンドを通じて、単にHost OSのFSを接続する用途だけでなく、コンテナ間で同じ作業空間を指す作業を進めることも可能です。 しかし、該当方式には問題点があります。 当然のことながら、Host OSの影響を大きく受けるということです。 特にWindowsのファイルシステムの場合、C:\、D:\のように始まることが一般的で、設定時にUnixやLinux系のパスとは異なる設定が必要という面倒さがあります。 開発時のWindowsは常に厄介です。 -v, --volume 前章ではcreate, run, execなど、dockerで使用可能な有用なコマンドと合わせてオプションを確認しました。 その中でbind mountを行うことができるオプションがこのオプションです。 $ docker [create|run|exec...] ... -v [HOST_PATH]:[CONTAINER_PATH] ... 上記のように使用でき、このコマンドを通じてHOST_OSのStorageとCONTAINERのStorageを接続できます。
2022年7月15日
[Docker] Docker Composeを学ぼう
お兄さんたち、私だけ不便を感じてる? 二回目のお兄さんたちです。実際、不便なことが多いからです。 Dockerの用途 Dockerはどんな時に使用するといったのか? Dockerの核心技術であるコンテナを使用したいときでしょう。 つまり、再利用のためです。 前に学んだDockerfileは、コンテナを作成するのに必要な多くの部分を自動化しました。 しかし、Dockerfileにも短所があります。 以前の投稿でも扱ったように、ホストOSの設定を自動化することには制限があるという部分でした。 例えば、ホストOSのポートフォワーディングや、ボリュームのパスをマウントすることまではできていませんでした。 結局、多くの開発者はDockerfileを作成し、 buildを通じて作成されたコンテナを相互に接続し、 volumeをマウントする必要がありました。 Docker Compose Docker Composeは上記の煩わしさを解決します。 docker-compose.ymlで定義できる内容にはvolume、port、envの他にコンテナを定義する様々な作業を実行できるようにしています。 また、単一コンテナだけでなく、多重コンテナを定義し、コンテナ間の関係を設定できるようにも支援しています。 Docker公式ドキュメントではComposeをプラットフォームに依存しないコンテナベースのアプリケーションとして紹介しています。 .yml, .yaml Docker Composeについて知る前に知っておかなければならないことがあります。 先にdocker-compose.ymlに多重コンテナに下すコマンドを設定できることを強調しました。 では、.ymlファイルとは何なのか? .yml、.yaml拡張子がついているファイルはYet Another Markup Languageという一種のマークアップ言語の一形態です。 まるでPythonのようにコロンとインデントを利用して階層を構成し、特定のオブジェクト、設定値などを簡単に記述することができます。 直感的に理解するために以下の例を見てみましょう。 car: name: "bus" color: "red" door: 4 capability: max_weight: "4T" human: 10 customers: - name: "Alice" age: 14 - name: "Ban" age: 16 - name: "Yang" age: 26 この形式の.yamlは以下のようなJSON形式でも表現できます。
2022年7月21日
--- title: "[Docker] Dockerfileを見てみよう。" type: blog date: 2022-07-13 weight: 3 comments: true --- ## 😡 皆さん、不便を感じているのは私だけ? DockerのCLIを少し試してみた方は、コンテナを作成して管理することがとても面倒だと感じたかもしれません。 私は簡単にしたいので、コンテナを作るたびに多くのコマンドを入力しなければなりません。 実際、それ以上に大きな問題があるとすれば、イメージをビルドする際、容量が驚くほど大きくなる可能性があるということです。 非常に大きくはないにしても、少なくとも100MBから、1〜2GBに達するものまで様々です。  多くのコンテナを管理する会社であれば、このようなことはさらなる災難として訪れる可能性があります。 容量はさておき、イメージを転送し、これを受け取るのにかかる時間は非常に長くなるでしょう。 ## 📄 Dockerfile そのためDockerには新たにコンテナを作る方法が提案されています。 作成済みのイメージではなく、**イメージを作るスクリプトを共有する**ことが主旨です。 ### 🚫 Don't Repeat Yourself どうせ一度は作らなければなりません。 ~~これを自動化することは後にAIがするのでしょうか..?~~ > _でも一度作ればいいのです。_ これはDockerの内部機能であるため、コマンドを作ってテキストファイルとして保存するよりもはるかに簡単で、形式的で、構造的です。 また、結論として`Dockerfile`も結局はテキストファイルなので、保存する際に大容量を占めることはありません。 では本題に入りましょう。 ### では、どうやって実行するのか? `Dockerfile`を作成すると、ファイルの仕様に従ってイメージを読み込み、コマンドを実行します。 コンテナがDockerに表示されると、そのイメージはユーザーのローカルに保存されます。 この過程を`build`と呼び、コンテナをイメージにする`commit`とは異なります。 ### `build [BUILD_PATH]` `build`コマンドは指定したパスの下位にある`Dockerfile`を基にコンテナを作成するコマンドです。 このコマンドは再帰的に実行されるため、絶対にルートディレクトリをパスとしてはいけません。 ```shell $ docker build / # (X) 通常、プロジェクトのルートディレクトリにDockerfileを置くため、以下のコマンドが慣用句のように使われます。