256

投稿日

更新日

Organization

Docker初学者がやるべきこと3選

この記事はNuco Advent Calendar 2022の22日目の記事です
スクリーンショット 2022-12-19 19.23.33.jpg

はじめに

対象読者

この記事では

  • Docker初学者の方
  • これからDockerを学ぼうとしている方

を対象にやるべきことして以下の3つを紹介します。

  1. Dockerの全体像を把握する
  2. チュートリアルで基本操作を学ぶ
  3. Docker Hubを散策する

自身が初学者だった頃の経験を基になるべく早く効率的にDockerを学ぶためにやるべきことを紹介するので参考にしてもらえれば幸いです。
スクリーンショット 2022-12-07 9.37.23.jpg

できるようになること

  • Dockerが何なのか理解できるようになります
  • Dockerを使ったアプリケーション開発に必要な基礎知識が身につきます
  • 記事TOPのクリスマスツリーをターミナルに表示できるようになります

1. Dockerの全体像を把握する

まずはDockerが何者であるかを把握しましょう。実際にコマンドで操作する前にざっくりイメージを膨らませておくことで理解のスピードが上がります。

Dockerはコンテナ型の仮想環境を提供するもの

Dockerは、Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのオープンソースソフトウェアです。
さてコンテナ型の仮想環境とはなんでしょうか?この用語を理解するために仮想環境とコンテナについて説明します。

仮想環境とは

仮想環境の仮想とは疑似的なという意味で使われています。仮想環境はコンピュータの中に疑似的に作った環境のことです。ここでの環境とは開発したり、テストしたり、実際にプログラムを動かしたりするために必要なコンピュータやソフトウェアなどが揃った場所と思ってください。仮想環境を構築することを仮想化といいます。
仮想環境を構築することで、Windows環境の中で仮想的に作られたLinux OS環境を用意したり、Windoiws環境の中にAndroid環境を用意してAndoroidアプリ開発を行ったりすることができます。
スクリーンショット 2022-12-13 1.26.51.jpg

コンテナ技術とは

コンテナとは仮想環境を構築する技術の1つです。物流業界で使われるコンテナは中に輸送するものを入れていますが、ここでいうコンテナの場合はアプリケーションが動くのに必要なものがまとまって入っている箱というイメージです。様々な環境においてコンテナで同じ仮想環境を作ることができ、環境ごとの違いによって発生する問題を減らすことができます。

スクリーンショット 2022-12-07 9.41.46.jpg

従来の仮想化とコンテナの違い

スクリーンショット 2022-12-13 2.51.44.jpg

従来の仮想化はアプリケーションが各々の仮想サーバの中で動作します。アプリケーションを起動するためには物理サーバにインストールされているホストOSとは別に仮想サーバ内でのゲストOSの起動が必要になります。
コンテナによる仮想化では仮想サーバとゲストOSが不要になります。コンテナエンジンがアプリケーションの起動に必要な環境(従来の仮想化のゲストOS)をそれっぽく再現しています。コンテナエンジンがコンテナにゲストOSがあるように見せているとも言えます。そのコンテナエンジンの中で最も有名なのがDockerです。
スクリーンショット 2022-12-13 3.22.32.jpg

Dockerを使うメリット

Dockerイメージで簡単に環境構築

初学者にとってはDockerコンテナとDockerイメージの違いがわかりにくいと思います。まずはDockerイメージとはDockerコンテナのテンプレートDockerコンテナはDockerイメージ(テンプレート)から起動したアプリケーションの動作環境くらいの理解で十分です。
Dockerイメージを共有することで誰でも簡単に同じ環境を用意することができます。

Dockerfileでイメージ構築手順をファイル化できる

DockerfileとはDockerイメージを作成するための手順が記されたテキストファイルです。Dockerイメージの設計図と説明されたりします。仮想環境を構築する手順をテキストで管理できます。
後述する基本コマンドの説明でDockerfileからDockerイメージを作成し、Dockerコンテナを起動するまでの流れを説明します。実際にコマンドを実行してみるとDockerfile、Dockerイメージ、Dockerコンテナそれぞれの役割と関係性が理解できると思います。
スクリーンショット 2022-12-19 19.51.35.jpg

軽量で早い

従来の仮想化と異なり、仮想サーバの立ち上げが不要なのでアプリケーションの起動が早いというメリットがあります。これにより開発作業をスムーズに行うことができます。
 

2. チュートリアルで基本操作を学ぶ

Dockerが何者であるかおおよそのイメージができたら、次はチュートリアルで実際の操作方法を学びます。公式のチュートリアルを終えるとDockerの基本操作はひととおり自信を持って行えるはずです。
また、本章の後半ではチュートリアルの復習も兼ねてよく使うコマンドを紹介するので、ぜひターミナルを開いて操作しながら読み進めてみてください。

やるべきは公式のチュートリアル

Dockerについて調べると、様々なブログや記事が見つかりますが、まずはじめにやるべきは公式のチュートリアルです。
Dockerのインストールが済んでいない方はこちらからインストールしましょう。
こちらのリポジトリに従ってチュートリアルを進めます。

まずはターミナルで次のコマンドを実行します。

$ docker run -d -p 80:80 docker/getting-started

この時点でコマンドの意味はわからなくても大丈夫です。チュートリアルを終える頃には理解できるようになっています。
コマンドを実行すると次のような出力が出てきます。
スクリーンショット 2022-12-08 8.05.24.jpg
ブラウザでhttp://localhost/ を開くと次のような画面が開きます。
スクリーンショット 2022-12-08 8.08.40.jpg
チュートリアルがとても丁寧に簡単な英語で説明されているので、英語のドキュメントに慣れていない方も頑張って読み進めてほしいです。Dockerを使ったアプリケーション開発をハンズオン形式で学ぶことができます。

和訳している方の記事がありましたので、どうしても英語が無理という方のためにリンクを貼らせていただきます。
Dockerを体系的に学べる公式チュートリアル和訳

まず覚えるべき基本コマンド

チュートリアルでも基本的なコマンドを学べますが、こちらでもおさえておくべきDockerコマンドを紹介します。
コマンドを実行しながら読み進めてみてください。

コンテナ一覧 docker ps

コンテナの一覧を確認するコマンドです。
前述したチュートリアルのコンテナが起動している状態で実行すると次のような出力が確認できます。

$ docker ps
CONTAINER ID   IMAGE                    COMMAND                 CREATED          STATUS         PORTS                              NAMES
1c064f6d6e88   docker/getting-started   "/docker-entrypoint.…" 26 minutes ago   Up 26 minutes  0.0.0.0:80->80/tcp, :::80->80/tcp  infallible_lewin

イメージ一覧 docker images

イメージの一覧を確認するコマンドです。
前述したチュートリアルのイメージがあると次のような出力が確認できます。

$ docker images
REPOSITORY                  TAG             IMAGE ID            CREATED             SIZE
docker/getting-started      latest          e5be50c31cd9        12 days ago         29.8 MB

コンテナ停止 docker stop

docker stop <CONTAINER IDまたはNAME>で起動中のコンテナを停止することができます。
CONTAINER IDが1c064f6d6e88のコンテナを停止する場合は

$ docker stop 1c064f6d6e88

NAME(ここではinfallible_lewin)を指定してコンテナを停止する場合は

$ docker stop infallible_lewin

停止したことを確認してみます。docker psは起動中のコンテナだけ表示するので、実行すると停止したコンテナは表示されなくなります。

$ docker ps
CONTAINER ID   IMAGE                    COMMAND                 CREATED          STATUS         PORTS                              NAMES

docker ps -aまたはdocker ps --allで停止中のコンテナを含めたすべてのコンテナを表示できます。
STATUSがExitedになっていることからコンテナが停止中であることが確認できます。

$ docker ps -a
CONTAINER ID   IMAGE                    COMMAND                 CREATED          STATUS                   PORTS        NAMES
1c064f6d6e88   docker/getting-started   "/docker-entrypoint.…" 26 minutes ago   Exited (0) 8 minutes ago              infallible_lewin

コンテナ起動 docker start

docker start <CONTAINER IDまたはNAME>でコンテナを起動することができます。
CONTAINER IDが1c064f6d6e88のコンテナを起動する場合は

$ docker start 1c064f6d6e88

NAME(ここではinfallible_lewin)を指定してコンテナを起動する場合は次のとおりです。

$ docker start infallible_lewin

イメージ作成 docker build

まず作成するDockerイメージの基となるDockerfileを作成します。

$ cat << EOS > Dockerfile
FROM nginx
EOS

エディターソフトでDockerfileという名前のファイルを作成し、FROM nginxとだけ入力して作成しても構いません。
Visual Studio Codeで作成するとこんな感じです。
スクリーンショット 2022-12-14 22.45.03.jpg
イメージを作成してみます。

$ docker build -t test:qiita .

-t test:qiitaはオプションでDockerイメージに名前とタグをつけています。ここではtestが名前、qiitaがタグです。
最後のピリオド.はDockerfileのある場所(カレントディレクトリ)を指定しています。
実行すると次のような出力が出てきます。
スクリーンショット 2022-12-14 22.52.12.jpg
ここで何が起こっているかというと、DockerfileにFROMで指定したnginxのイメージをDocker Hubから取得(pullといいます)してローカルPC上にDockerイメージを構築しています。
Docker HubとはDockerイメージを検索・共有するためにDocker社が提供しているサービスです。平たく言うとGitHubのDockerイメージ版です。

docker imagesでDockerイメージが作成されていることが確認できます。

$ docker images
REPOSITORY          TAG         IMAGE ID       CREATED        SIZE
test                qiita       7f7b4ac1ce1f   13 hours ago   142MB

コンテナを起動状態で作成 docker run

作成したDockerイメージからDockerコンテナを作成し、起動してみます。
ここではコンテナを起動した状態で作成するdocker runを使用します。

$ docker run -d -p 8080:80 --name test-container test

-dはコンテナをバックグラウンドで動作させるオプションです。
-p 8080:80はローカルPCのポート8080をコンテナのポート80を結びつけます。
--name test-containerは起動するコンテナにtest-containerという名前をつけています。ここでつけた名前はdockerコマンドでコンテナの指定に使えます。
最後のtestは基となるDockerイメージの名前です。

docker psでDockerコンテナが作成されているか確認します。

$ docker ps
CONTAINER ID   IMAGE     COMMAND                 CREATED         STATUS         PORTS                                  NAMES
09015830f07d   test      "/docker-entrypoint.…" 3 minutes ago   Up 3 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp  test-container

コンテナの起動が確認できました。
ブラウザでhttp://localhost:8080 を開くと次のような画面が表示されます。docker run-pオプションでローカルPCのポート8080とコンテナのポート80がマッピングされているので、nginxのWebページが表示されます。

80番ポート
インターネットでWeb閲覧をしているとき、ユーザーのPCとサーバと呼ばれるコンピュータが「TCP/IP」と呼ばれるプロトコル群を使って一対一の通信を行なっています。しかし、IPアドレスだけでは利用したいサービスを識別できないため、サーバ側ではアプリケーションプロトコルごとに固定的に割り当てられたポート番号が用意されています。
ポート番号は0から65535まで存在しますが、そのなかでも0~1023までをウェルノウンポート番号といい、IANAという団体により管理されています。TCP/IPにおいて通信で利用されるポート番号のうち、メジャーなサービスやプロトコルが利用するために予約されているポート番号がウェルノウンポート番号です。
80番ポートはHTTPでWebサーバがクライアントサーバと通信する際に利用されます。

スクリーンショット 2022-12-14 23.51.38.jpg

コンテナを削除 docker rm

Dockerを使って開発をしていると使わなくなったコンテナを削除することがあります。初心者の場合はコンテナを削除することをためらうかもしれませんので、ここでしっかり削除する流れを学んでおきましょう。
まずdocker psでコンテナを確認します。

$ docker ps
CONTAINER ID   IMAGE     COMMAND                 CREATED         STATUS         PORTS                                  NAMES
09015830f07d   test      "/docker-entrypoint.…" 15 minutes ago   Up 15 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp  test-container

docker stopでコンテナを停止します。
ここではNAMEを指定して停止します。IDを指定しても構いません。

$ docker stop test-container

docker ps -aでコンテナの停止を確認します。

$ docker ps -a
CONTAINER ID   IMAGE    COMMAND                 CREATED          STATUS                    PORTS        NAMES
09015830f07d   test     "/docker-entrypoint.…" 16 minutes ago   Exited (0) 15 seconds ago              test-container

コンテナの停止を確認したら削除してみましょう。
docker rm <CONTAINER IDまたはNAME>でコンテナを削除することができます。
ここではNAMEを指定して削除します。

$ docker rm test-container

docker ps -aでコンテナが削除されていることが確認できます。

$ docker ps -a
CONTAINER ID      IMAGE      COMMAND      CREATED      STATUS       PORTS        NAMES

コンテナを停止状態で作成 docker create

再びDockerイメージからDockerコンテナを作成してみます。先程はdocker runで作成しましたが、ここではdocker createを使用します。
docker rundocker createはどちらもコンテナを作成するコマンドですが、作成されるコンテナが起動状態か停止状態かという違いがあります。docker runはコンテナを起動状態で作成し、docker createはコンテナを停止状態で作成します。
docker run = docker create(コンテナ作成) + docker start(コンテナ起動)と覚えておきましょう。
実際にコマンドを実行してみます。

$ docker create -p 8080:80 --name test-create test

停止状態でコンテナを作成したのでdocker ps -a(停止中も含めたすべてのコンテナを表示)で確認します。

$ docker ps -a
CONTAINER ID   IMAGE    COMMAND                  CREATED          STATUS        PORTS       NAMES
b5f4e819a872   test     "/docker-entrypoint.…"  2 minutes ago    Created                   test-create

docker rmでコンテナを削除しておきます。ここではCONTAINER IDを指定して削除します。

$ docker rm b5f4e819a872

イメージを削除 docker rmi

docker rmiはイメージを削除するコマンドです。
まずdocker imagesでイメージ一覧を確認します。

$ docker images
REPOSITORY          TAG         IMAGE ID       CREATED        SIZE
test                qiita       7f7b4ac1ce1f   13 hours ago   142MB

docker rmi <REPOSITORY:TAGまたはIMAGE ID>で削除することができます。
ここではREPOSITORY:TAGでイメージを指定して削除してみます。

$ docker rmi test:qiita

最後にdocker imagesで削除されていることを確認しましょう。

$ docker images
REPOSITORY          TAG         IMAGE ID       CREATED        SIZE

使用していないDockerイメージを放置しておくと、いつの間にかディスク容量を圧迫していることになりかねないので、使わないイメージは削除しておきましょう。

イメージを取得 docker pull

DokckerHubからイメージをpull(取得)するコマンドです。Docker Hubにある多くの構築済みのイメージから特定のイメージをダウンロードして使うことができます。

$ docker pull lukaszlach/merry-christmas

例でpullされるイメージlukaszlach/merry-christmasでコンテナを実行すると記事TOPのクリスマスツリーが現れるので試してみてください。
クリスマスツリーのイメージのDocker Hubはこちら

コンテナ内でコマンド実行 docker exec

docker execは起動中のコンテナ内で指定したコマンドを実行します。
いくつか例を試してみます。準備としてexecコマンドを試すためのコンテナを起動します。

$ docker run -d -p 8080:80 --name test-exec nginx

docker psで起動を確認します。

$ docker ps
CONTAINER ID  IMAGE  COMMAND                CREATED        STATUS         PORTS                                   NAMES
bc20a5650fe5  nginx  "/docker-entrypoint.…" 4 seconds ago  Up 3 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp  test-exec

まずはexecコマンドを使ってコンテナ内でlsコマンドを実行してみます。

$ docker exec test-exec ls -l /usr

test-execはコンテナ名、ls -l /usrがコンテナ内で実行するコマンドです。
以下のようにコンテナ内の/usrディレクトリ下のファイル一覧が出力されます。

total 36
drwxr-xr-x 1 root root 4096 Dec 14 01:20 bin
drwxr-xr-x 2 root root 4096 Sep  3 12:10 games
drwxr-xr-x 2 root root 4096 Sep  3 12:10 include
drwxr-xr-x 1 root root 4096 Dec 14 01:20 lib
drwxr-xr-x 3 root root 4096 Sep 24  2020 libexec
drwxr-xr-x 1 root root 4096 Dec  5 00:00 local
drwxr-xr-x 1 root root 4096 Dec 14 01:20 sbin
drwxr-xr-x 1 root root 4096 Dec 14 01:20 share
drwxr-xr-x 2 root root 4096 Sep  3 12:10 src

次はよく利用するコンテナ内でシェルを起動する場合を試してみます。

$ docker exec -it test-exec bash

-it-i -tと同じで-iは標準入力を開き続けるオプション、-tは疑似ttyを割り当てるオプションです。
とりあえずは-it手元の環境でdocker内コマンド入力ができるようになると覚えておけばよいでしょう。

コマンドを実行すると以下のようにプロンプトが#に変わるはずです。このプロンプトはdocker execで実行したコンテナ内のbashが出力しているプロンプトです。
@のあとの文字列bc20a5650fe5はコンテナIDです。先程docker psで確認したコンテナIDと同じです。

root@bc20a5650fe5:/#

このプロンプトで実行するコマンドはコンテナ内で実行することになります。lscdなど色々なコマンドを実行みてください。
コンテナ内のシェルを終了するときはexitを実行します。

root@bc20a5650fe5:/# exit

最後にコンテナとイメージを削除しておきます。
docker rmについている-fオプションは起動中のコンテナを強制的に削除します。

$ docker rm -f test-exec
$ docker rmi nginx

3. Docker Hubを散策する

やるべきこと3つ目はDocker Hub散策です。様々なイメージのDockerfileを見て勉強しましょう。

Docker Hubとは

前の章でも簡単に触れましたが、Docker HubとはDocker社が運営しているDockerイメージをアップロードして公開・共有できるサービスで、ここで公開されているイメージは自由にダウンロードして使うことができます。公開されているコンテナのベースになっているDockerfileを見ることができるので、Dockerfileの作成に慣れていない方はとても参考になると思います。
Docker Hub

公式イメージのDockerfileを見てみる

試しにpythonの公式イメージを見てみます。Simple Tagsの一番上のリンクを踏んでみます。
スクリーンショット 2022-12-08 9.17.29.jpg
GitHubでDockerfileを見ることができます。公式イメージは無駄がなくベストプラクティスにしたがって書かれているので、是非参考にしてみてください。
スクリーンショット 2022-12-08 9.20.44.jpg

さらに理解を深めたいあなたへ

Dockerfileのベストプラクティス

最後にDockerfileのベストプラクティスを紹介させていただきます。

保守性が高く軽量で効率的なイメージを作成するためにDocker社が推奨しているものです。
.dockerignoreの使い方ADDとCOPYの違いなどを学ぶことができます。公式チュートリアルを終えたあとはこちらを学ぶことでより実践的な力が身につくでしょう。

おわりに

最後まで読んでいただきありがとうございます。
弊社では、経験の有無を問わず、社員やインターン生の採用を行っています。

興味のある方はこちらをご覧ください。

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
ログインすると使える機能について

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
256