🐧

Linux 使いになりたい人向けの Intel N100 ミニ PC で構築する開発環境(11)- Docker

2024/07/06に公開

はじめに

これは、Linux 使いになりたい人向けに Intel N100 ミニ PC を使って開発環境を構築する方法を解説する記事の第11弾です。第1弾はLinux 使いになりたい人向けの Intel N100 ミニ PC で構築する開発環境(1) - 構築する開発環境について にあり、そこから第2弾へと続いています。そちらからご覧ください。

ここで使用する Intel N100 ミニ PC の仕様は次のものを前提とします。

項目 内容
OS Windows 11 Pro
CPU Intel N100
メモリ 16GB
ストレージ SSD 512 GB
画面出力端子 HDMI×2
WiFi 5G/2.4G
イーサネット RJ45×1
Bluetoot BT4.2
USB USB3.0×2/USB2.0×2

このマシンで最終的に Windows と Ubuntu Desktop が使えるように環境構築することを目指します。zenn.dev を購読している人のレベルを考えると、画面キャプチャはそれほど必要がないと考えているため少なめです。また、説明についても明示しないとわかりにくいと思われるものに絞っているので少なめです。

今回は Docker について説明します。コマンド実行にあたっては Linux に慣れるということも考慮して、基本的に Git Bash や WSL を使うようにします。

Docker とは

Docker は、アプリケーションをコンテナーと呼ばれる軽量な仮想環境にパッケージ化、配布、実行するためのオープンソースプラットフォームです。コンテナーには、アプリケーションに必要なコード、ランタイム、システムライブラリ、設定ファイルなどがすべて含まれていて、コンテナーが稼働するマシンとは別に仮想マシンがあるかのように動作します。

ただし、コンテナーが稼働するホストマシンの OS とコンテナー内で動作する OS のカーネルは同じものが使われます。仮想マシンを動かすことができる仮想化ソフトウェアであれば、仮想マシンが稼働するホストマシンの OS と仮想マシンの OS は別のものが使えますが、Docker では別のものにすることができません。Docker Linux の同じカーネルが使われます。

Docker の主な特徴

Docker の特徴としては次の事項を挙げることができます。

  • 動作が軽い
  • 移植しやすい
  • 再現性が高い
  • 分離性が高い
  • 効率性が高い

動作が軽いというのは、似たようなことが実現できる仮想マシンと比較して軽量で、起動や実行が高速だということです。仮想マシンを使うには、Hyper-V や VirtualBox といった仮想化ソフトウェアで仮想マシンを作成してから、そこに OS へインストールする必要があります。仮想化ソフトウェアでは物理的なハードウェアをソフトウェアで仮想的なハードウェアとして実装しているため、その分、処理が重くなります。Docker では OS のカーネル機能をそのまま使うので、処理が軽くなります。

移植しやすいというのは、Docker が稼働するホストマシンの OS の環境について、基本的に意識することなく、使いたいソフトウェアを動かすことができるということです。Docker で動かすことができるソフトウェアは Linux 用のものになりますが、Linux ではディストリビューションによって環境が異なるので、それぞれのディストリビューションに合わせてソフトウェアのパッケージを用意する必要があります。Docker で動作するようにソフトウェアを用意すれば、ディストリビューションの違いについて考慮しなくても済むようになります。

再現性が高いというのは、異なるマシンで同じ環境を簡単に構築可能になるということです。コンテナーの設定ファイルと Docker が動く環境があれば、マシンが違っていても同じコンテナーを同じ条件で動作させることができます。Docker は Windows、macOS でも動かすことができるため、同じ設定で動作するコンテナーを Linux マシンだけでなく、Windows や macOS で動かすこともできます。

分離性が高いというのは、他のコンテナーやホストマシンに大きな影響を与えることなく実行可能だということになります。カーネルは同じものを使うので、まったく影響なしということにはできませんが、いくつかの制限に注意すれば良いだけです。たとえば、開発などで使用したい HTTP サーバーや DB サーバーについて、複数のバージョンを対象としたいときは、従来だと共存環境の構築したり、複数のマシンを用意して環境を構築するなどの対応が必要で大変でした。Docker を使えば、バージョンが異なる Web サーバーや DB サーバーを、それぞれの環境を隔離した状態で動かすことができます。

効率性が高いというのは、Docker を使うとハードウェアリソースを効率的に活用可能となるということです。ここまでの説明でいくつか出てきましたが、従来だと複数マシンの用意が必要だったり、仮想マシンを使うなどして対応してきた作業について、Docker を使うことで、これらを必要としなくなっています。仮想マシンではソフトウェア的にハードウェアを実装して動かす分、CPU やメモリーが余計に必要となります。Docker を使うと、そういったオーバーヘッドがなくなり、効率が良くなります。

Docker を利用するメリット

Docker を利用するメリットは次になります。

  • 開発・テストの効率化
  • デプロイの迅速化
  • 運用管理の簡素化
  • リソース利用の効率化

開発環境と商用環境で同じソフトウェアを使うことで、開発・テストの効率が向上します。一般的には開発時は開発しやすい環境でプログラムコードを作成したり修正したりします。しかし、商用環境では安全に効率よく動かすことを優先した環境でプログラムを実行します。そのため、厳密には微妙に違った環境でプログラムを動かすことになるため、商用環境でないと再現しないバグが発生することがよくあります。そういったことが少なくなるように、Docker を利用することができます。

Docker を使うと、デプロイの迅速化が可能になります。コンテナーは設定ファイルを用意するだけで簡単にデプロイすることができるようになります。Docker がなかった頃は、開発中のソフトウェアが新しいソフトウェアに依存するようになったときには、開発担当から運用担当へ情報を提供して、運用環境で問題が起きないように調整をしながらデプロイをする必要がありました。Docker を使っても情報共有自体は必要ですが、担当間で Docker 用の設定ファイルを共有して、それぞれで検証して問題があれば調整するといった作業がしやすくなりました。デプロイの迅速化により、アプリケーションのリリースサイクルを短縮することができます。

共用の開発環境で使用するソフトウェアを Docker コンテナーに統一して管理することで、その環境の運用管理が簡素化されます。開発者が普段の開発で使う Docker コンテナーと同じものを使うことで、開発者のパソコンと共用の開発環境用サーバーマシンとの間の環境差はあまり大きくはなりません。また、商用環境で使う Linux ディストリビューションと同じ環境の Docker コンテナーを開発でも使うようにすれば、ステージング環境や商用環境のために用意したサーバーマシンと開発者のパソコンとの間の環境差もあまり大きくなりません。開発者の開発環境と商用環境との差が少ない方が、全体の運用管理が簡素化されます。もし、こういった環境の差が大きい場合は、運用上は、その差についての管理も必要となります。

Docker を使うと、複数のコンテナーを単一のホストマシン上で実行することができるようになり、ハードウェアリソースを効率的に活用できるということになります。

なお、Docker を使うためには Linux という OS が動作するコンピュータマシンが必要になります。
Windows や macOS ではコンピュータマシンを仮想マシンなどで用意して利用できるようにします。
Docker Desktop をインストールすると、この Docker 用の仮想マシン環境も自動で構築してくれるので、非常に手軽に Docker を使えるようになります。

Docker と Linux

Docker には Linux という OS が動作するコンピュータマシンが必要だと説明しました。OS の基本機能部分であるカーネルに Linux カーネル(https://www.kernel.org/)を採用しているものを Linux といいます。Linux カーネルは Linus Torvalds 氏が個人で開発を始めたオープンソースソフトウェアです。

Linux カーネルを採用している OS には色々あって、Linux ディストリビューションと呼ばれています。有名なものとしては次に挙げるものがあります。

これらについて、OS のカーネルは Linux カーネルで共通していますが、カーネルと組み合わせている周辺システムが違います。周辺システムには、パッケージ管理用のシステム・システム設定用ソフトウェア・GUI を提供するソフトウェアなどが含まれます。

Linux の知識がなくても Docker を利用することはできますが、Linux の知識があるとより有効に Docker を利用することができるようになります。

Docker Desktop とは

Docker を使うためには Docker Desktop というソフトウェアをインストールして使うのが簡単です。Docker Desktop は、Docker 環境を簡単に構築・利用できる公式の GUI アプリケーションです。次に挙げる主要な OS をサポートしています。

  • Windows
  • macOS
  • Linux

また、Docker Desktop には次のソフトウェアが含まれています。それぞれのソフトウェアについては、この後に説明します。

  • Docker Engine
  • Docker CLI
  • Docker Compose

Docker Desktop の公式 Web サイトは https://www.docker.com/products/docker-desktop/ になります。ドキュメントは https://docs.docker.com/desktop/ にあります。

Docker Desktop は、個人で利用する場合は無料です。商用で利用する場合、無料で利用するには条件があります。https://www.docker.com/pricing/ を確認してください。2024 年 6 月時点では「Commercial use of Docker Desktop at a company of more than 250 employees OR more than $10 million in annual revenue requires a paid subscription (Pro, Team, or Business).」とあり、従業員数と年間売上によって有料となる場合があります。

Docker Desktop の主な機能としては次のものが挙げられます。

  • Docker コマンドの GUI 操作
  • Docker イメージのプル、ビルド、管理
  • Docker コンテナーの操作、管理
  • Docker ボリュームの管理
  • Docker ネットワークの管理
  • Docker の設定
  • 拡張機能

Docker Desktop を使うと、ターミナルで Docker コマンドを直接入力しなくても、GUI で直感的に Docker 関連の操作ができるようになります。

Docker を使うには、Docker イメージを Docker Hub Container Image Library などの Docker レジストリからプルする必要があります。また、既存の Docker イメージをカスタマイズするためにビルドしたり、ローカルにキャッシュされた Docker イメージを削除したりして管理します。こういった作業を Docker Desktop では GUI 操作ですることができます。

また、Docker コンテナーを起動したり、起動中のコンテナーを一覧表示することもできます。コンテナーの停止、再開、削除といった操作もできます。Docker コンテナーのログを確認したりすることもでき、Docker コンテナーを管理するために必要な機能が揃っています。

Docker でファイルデータを永続化するには、Docker ボリュームというものを利用します。これの作成、一覧表示、削除といった操作をして管理することができます。

Docker コンテナーでネットワーク機能を使うには、Docker ネットワークというものを利用します。これの作成、一覧表示、削除といった操作をすることで、Docker が利用するネットワークの管理ができます。

Docker の設定を変更するための設定画面もあります。ネットワーク経由で利用できるように設定したり、Docker Desktop のソフトウェア更新のための設定を指定したりすることができます。

Docker Desktop には拡張機能もあります。次のような拡張機能を追加することもできて、機能の拡張ができます。

機能拡張名 説明
Resource usage リソースの利用状況の確認
Volumes Backup & Share Dcoker ボリュームのバックアップと共有
Disk Usage ディスクの利用状況の確認
Logs Explorer ログの確認
Portainer コンテナーの管理用

なお、Docker Desktop は、Docker CLI(コマンドライン)と併用して利用できます。Docker Desktop で GUI 操作に慣れてきたら、Docker CLI を併用することで、より効率的に Docker を利用することができます。

Docker Desktop は、Windows、macOS、Linux 上で Docker 環境を簡単に構築・利用できる便利なツールです。Docker を初めて利用する方や、GUI で操作したい方におすすめです。

Docker Engine とは

Docker Engine は Docker コンテナーを動作させるために必要な機能を提供するソフトウェアで、Docker のコアとなるソフトウェアです。公式のドキュメントは https://docs.docker.com/engine/ にあります。ライセンスは Apache License バージョン 2.0 です。

Docker Engine は、次の機能を備えたクライアントサーバーアプリケーションとして機能します。API は Application Programming Interface の略で、このインターフェースを使うことで、リモートからプログラムの実行ができます。

  • 長時間実行されるデーモンプロセスを持つサーバー(dockerd)
  • プログラムが Docker のデーモンプロセスと通信して命令するための API(Docker API)
  • CLI(command line interface)クライアント(docker)

/images/20240630_docker/docker-02.png
Docker Engine

Docker Engine には、Linux でデーモンプロセスとして動作する dockerd というソフトウェアが含まれます。デーモンプロセスとは、利用者の対話的な操作を処理するプロセスとは別にバックグラウンドで動作するプロセスの一種です。

dockerd を動作させるプロセスは、Docker デーモン(Docker daemon)と呼ばれることもあります。また、dockerd が動作するコンピュータマシンを Docker ホスト(Docker host)と呼びます。

dockerd は Docker サーバとして動作し、Docker API に対応するサービスを提供します。dockerd は、この API を通じて Docker クライアントから命令を受け取り、命令に応じた処理を実行します。

dockerd は、Docker 用のイメージ、コンテナー、ネットワーク、ボリュームなどの Docker オブジェクト (Docker Object) を作成し管理するための機能を持っています。Docker オブジェクトについては、後で説明します。

Docker CLI などのクライアントは、Docker API を使用して Docker デーモンへ命令し、Docker オブジェクトの制御や操作をします。Docker Desktop など、他の多くの Docker アプリケーションは、基盤となる Docker API と Docker CLI を内部的に使用します。

Docker API については Develop with Docker Engine API にドキュメントがあります。

Docker はクライアントサーバーアプリケーションなので、仕組み上は Docker CLI を動かす Docker クライアント用のマシンと dockerd を動かす Docker ホストは別のマシンにすることができます。ただし、クライアント用とホスト用に別々のマシンを用意する必要があるわけではなく、同じマシンに用意して使うことも可能です。実際に、Docker Desktop を使う場合は、Docker クライアントを動かすマシンと Docker ホストは同じパソコンになります。利用するにあたって、用意が必要なパソコンは 1 台で大丈夫です。

Docker CLI

Docker CLI は Docker 用のコマンドライン・インタフェース(Command Line Interface、CLI)を提供するソフトウェアです。具体的には docker コマンドなどが含まれます。

docker コマンドを使って Docker コンテナーの起動や削除をすることができます。docker コマンドは Docker コンテナーの起動や削除の命令を dockerd へしているだけなので、実際の処理は dockerd が担当しています。

コマンドの実行例としては次のようになります。

docker run --rm -i -t ubuntu /bin/bash

ここでは、ubuntu のイメージを使って、/bin/bash コマンドを実行しています。

Docker Compose

Docker を利用するときは Docker コンテナーなどの Docker オブジェクトを組み合わせて使います。また、複数の Docker コンテナーを組み合わせて使いたいときもあります。使用する Docker オブジェクトについて、Docker Compose を使うと、宣言的にファイルで設定をすることができて管理しやすくなります。

Docker Compose では Docker オブジェクトをどのように組み合わせて利用するかを compose.yaml という設定ファイルに記述します。少し前の資料だと docker-compose.yaml とか docker-compose.yml といったファイル名で紹介されていることもあります。

動かしたいソフトウェア実行環境用の compose.yaml を指定して Docker Compose のコマンドを実行すると、すぐにその環境を動作させることができます。compose.yaml のサンプルは、次のようなものになります。

compose.yaml
name: gitea

services:
  gitea:
    image: gitea/gitea:1.21.4
    container_name: gitea
    hostname: gitea
    restart: always
    volumes:
      - gitea-data:/data
    networks:
      - gitea-net
    ports:
      - "127.0.0.1:3000:3000"
      - "127.0.0.1:2222:22"
    environment:
      - USER_UID=1000
      - USER_GID=1000

volumes:
  gitea-data:
    name: gitea-data

networks:
  gitea-net:
    name: gitea-net

ここでは設定内容についての詳細説明はしませんが、services: で使用するコンテナー、volumes: で使用するボリューム、networks: で使用するネットワークを定義しています。このファイルを見ると、ソフトウェアを実行するときに必要な Docker オブジェクトや環境がわかるようになります。

このファイルを用意するメリットは、動作させるパソコンが違っていても、同じ設定ファイルを使ったソフトウェア実行環境なら、ソフトウェアは同じように動作するということです。Web アプリの実行環境は Web サーバとデータベースサーバなどの複数のソフトウェアを組み合わせる必要があり、パソコンを変える度に設定をするのは大変です。Docker Compose を使うことで、そういった実行環境が手軽に手元で再現できるようになります。

また、compose.yaml という設定ファイルでソフトウェアの実行環境をテキストファイルで管理できるようになるので、これをソフトウェアのソースコードと一緒に管理することで、ソフトウェアの実行環境もバージョン管理することができるようになります。

なお、最新版の docker コマンドでは Docker Compose の機能はプラグインとして実装されていて、docker compose コマンドで使えるようになっています。Docker Compose のバージョンが 2 より古いものでは、docker コマンドとは別に docker-compose コマンドがあって、それを使っていました。こういった経緯があるため、Docker Compose を docker-compose のように表記することもあります。

Docker のアーキテクチャー

Docker のアーキテクチャーについて、公式のドキュメントは https://docs.docker.com/get-started/overview/#docker-architecture にあり、アーキテクチャの図は https://docs.docker.com/get-started/images/docker-architecture.webp のようになっています。これを参考にして重要な部分を図にしたものは次のようになります。

/images/20240630_docker/docker-01.png
Docker のアーキテクチャー

Docker デーモン (dockerd) は Docker API による接続を待機して、リクエストがあったら、その内容に応じて、Docker イメージやコンテナーなどの Docker オブジェクトの管理をします。他のデーモンと通信して連携させることもできます。

/images/20240630_docker/docker-02.png
Docker デーモン

Docker クライアント (docker) は Docker ユーザーのための対話型インタフェースを提供します。docker container run コマンド(docker run に相当)などを実行すると、クライアントは dockerd へ Docker API を使って命令を出し、dockerd はそれを実行します。Docker クライアントは命令を出す先の Docker デーモンを、環境変数を使うなどして切り替えることができます。

Docker レジストリは Docker イメージを保管します。デフォルトの Docker レジストリとしては Docker Hub が用意されています。これは、無料で利用可能な状態で公開されているパブリックなレジストリです。Docker レジストリを自分で用意することもできます。

Docker コンテナーを使うにあたっては、docker image pull コマンド(docker pull コマンド)に相当する処理を実行して、Docker レジストリから Docker イメージを取得します。

/images/20240630_docker/docker-03.png
Docker レジストリ

それから docker container run コマンド(docker run コマンド)に相当する処理を実行して、Docker ホストにキャッシュしてある Docker イメージを使って Docker コンテナーを稼働させます。このとき、Docker ホストに Docker イメージがキャッシュされていない場合は自動で docker image pull コマンド相当の処理が実行されて Docker イメージの取得をしてから、Docker コンテナーの稼働をするという処理になります。

なお、docker build コマンドを使うと自作の Docker イメージを作成することができます。このコマンドで作成した自作の Docker イメージは Docker ホストで使えるようになります。これを Docker レジストリへ保管して他のマシンでも簡単に利用できるようにしたい場合は、docker image push コマンドに相当する処理を実行して Docker レジストリへ Docker イメージを登録します。

Docker オブジェクト

Docker オブジェクトには、Docker コンテナー・Docker イメージ・Docker ボリューム・Docker ネットワークなどがあります。

ここでは、Docker コンテナーは軽量な仮想マシンのようなものと考えておけば良いです。Docker イメージは、この仮想マシンのようなものが利用する仮想的な起動ディスクイメージになります。Docker ボリュームは、この仮想マシンのようなものが利用する専用の仮想的なストレージになります。Docker ネットワークは、この仮想マシンのようなものが利用する専用の仮想的なネットワークになります。

ここで、Docker コンテナーと Docker イメージの関係については重要なので、説明しておきます。

Docker イメージは、Docker コンテナー用の仮想的な起動ディスクイメージだと説明しました。普通のパソコンや仮想マシンで使われている起動ディスクとちがって、コンテナーによってファイルシステムの更新はされません。Docker イメージは、Docker コンテナー専用の起動ディスクイメージのようなもので、読み取り専用のテンプレートデータだと考えておけば良いです。

Docker イメージはコンテナーから更新することはできませんが、イメージのビルドをすることでカスタマイズすることができます。カスタマイズした Docker イメージは、Docker レジストリというものへ登録することができます。Docker レジストリは、Docker イメージを管理するためのシステムで、ここに登録されている Docker イメージは他のマシンで簡単に利用することができるようになります。

Docker イメージを用意するにあたっては、ベースとなる別の Docker イメージを指定し、そこに実行するアプリケーションと、それに必要なライブラリをインストールして構成します。ユーザーなどが必要なら、ユーザーの追加などもします。こういった構築するイメージについての手順は Dockerfile というファイルに記述し、これを使ってイメージをビルドします。

ここで、Dockerfile の手順によって更新されたファイルシステムの差分はレイヤー(層)で管理されます。ビルドのしなおしをするときは、レイヤーで差が発生した部分だけ処理をしなおします。この仕組みにより高速なビルドが実現できるようになっています。ここでは、詳しいことは理解しなくても良いので、Docker イメージにはレイヤーという概念があるということだけ覚えておきましょう。

Docker コンテナーは Docker イメージから作成される実行可能なインスタンスです。Docker API や Docker CLI を使って、コンテナーの作成、開始、停止、削除といった操作ができます。コンテナーが使うネットワークやストレージを指定することもできます。また、実行中のコンテナーから Docker イメージを作成することもできます。

デフォルトの設定では、コンテナーは他のコンテナーホストマシンから比較的よく隔離されています。この隔離について、どの程度のものにするかについては調整することができます。

コンテナーの動作や用意されるコンテナー用の環境は、使用するイメージとコンテナーの作成時に指定する設定によって定義されます。また、コンテナーが削除されると、永続ストレージ永続ストレージに保存されていないコンテナの状態の変更はすべて破棄されます。そのため、コンテナーを作成すると、必ず同じ初期状態のものになります。

この性質があるため、ソフトウェアのテストや、アプリケーションの試用をするときに、コンテナーを使うと便利なのです。

Docker レジストリ

Docker イメージは Docker レジストリから入手することができます。よく使われている Docker レジストリとしては Docker 社が提供する Docker Hub(https://hub.docker.com/)があります。基本的には、ここで公開されているものを使います。

Docker のエコシステムでは、Docker レジストリ(registry)という、Docker イメージを保存して配布するためのシステムが用意されていて、基本的にはそれを使って管理します。

Docker レジストリには、次のような種類があり、Docker を初めて使う人はデフォルトのレジストリとなっている Docker Hub を使うことが多いはずです。

種類 説明
パブリックレジストリ インターネット上で公開されていてユーザー制限がない公共用途のレジストリ
プライベートレジストリ LAN 環境に用意され、利用可能なユーザーが制限されているなど、アクセス元を制限した専用レジストリ
クラウドサービスのレジストリ 主にビジネス用途を想定したパブリッククラウドのサービスとして使用可能なレジストリ

パブリックレジストリとクラウドサービスのレジストリの分類はしにくいですが、個人が無料で利用できるものか、ビジネス用途で有料で利用することを想定して利用するものなのかで個人的な見解で分けています。

各レジストリの例については、次のものがあります。

Docker HubGitHub Packages では、世界中の開発者が Docker イメージを登録していて、それを検索したり、利用したりすることができるようになっています。ビジネス的に自社でパブリックレジストリのクラウドサービスを構築できる会社は、自社が提供する Docker イメージを Docker Hub ではなく自社のパブリックレジストリで提供していることが多いので、検索したり、利用したりするときは、そちらを使ったほうが良いことがあります。

こういった Docker レジストリに自分が使いたい Docker イメージがない場合は、自分でカスタマイズしたものをビルドして作成することもできます。また、Docker レジストリを自分で用意して、カスタマイズした Docker イメージをそこへ登録して利用するといったこともできます。

Docker CLI の使い方

Docker イメージの管理や Docker コンテナーの操作をするにあたって、基本的には Docker Desktop や VS Code の Docker 拡張機能を使うのですが、なにかトラブルがあった場合には Docker クライアントである Docker CLI の docker コマンドを使います。ここでは、Docker のアーキテクチャを理解するために、docker コマンドと合わせて説明します。

Docker CLI の基本的なコマンド

Docker コンテナーを使うには、Docker レジストリにある Docker イメージを Docker ホストにダウンロードする必要があります。ダウンロードされたイメージは Docker ホストにキャッシュされるので、Docker コンテナーを起動する度に Docker イメージをダウンロードしなくても済むようになります。

具体的な操作としては、docker image pull コマンドを使います。Docker Desktop でも、このコマンドに相当するメニューが用意されています。

docker image pull <イメージ名>

これで、Docker クライアントから Docker ホストの Docker デーモンへ Docker イメージを Docker レジストリからダウンロードする命令が出されます。Docker の デーモンは Docker レジストリから Docker イメージをダウンロードして、Docker ホストへ保存します。

次に Docker コンテナーを起動します。そのためには、docker container run コマンドを実行します。

docker container run <イメージ名>

これで、Docker クライアントから Docker ホストの Docker デーモンへ、指定した Docker イメージを使って Docker コンテナーを作成し、起動する命令が出されます。Docker の デーモンは Docker イメージから Docker コンテナーを作成して起動します。

起動している Docker コンテナーの一覧を表示するには docker container ls コマンドを使います。停止しているものも含める場合は -a オプションを指定します。

docker container ls -a

これで、docker container run コマンドのときと同じように、Docker クライアントから Docker ホストの Docker デーモンへ Docker コンテナーの一覧を表示する命令が出され、Docker デーモンがそれを実行します。その結果、動作中のコンテナーの一覧が表示されます。この後も、同様に Docker クライアントから命令が出て、 Docker デーモンが実行するので、これについての説明は省略します。

起動している Docker コンテナーを停止するには docker container stop コマンドを使います。

docker container stop <コンテナー名>

停止した Docker コンテナーは docker container start コマンドで再開することができます。

docker container start <コンテナー名>

停止している Docker コンテナーについて、使い終わって破棄したい場合は、docker container rm コマンドを使います。Docker に慣れていないと、Docker イメージに影響がありそうに思うかもしれませんが、Docker イメージは Docker コンテナーを作成する時にしか使わないので影響しません。

docker container rm <コンテナー名>

使わなくなった Docker イメージを削除するには、docker image rm コマンドを実行します。

docker image rm <イメージ名>

docker コマンドの使用例

簡単なコマンドについて説明したので、ubuntu イメージを使った実行についても説明しておきます。

ここでは、ubuntu イメージをプルしてから、それを使って /bin/bash のシェルを実行するコンテナーの起動をしてみましょう。また、停止、再開、破棄の順に試してから、最後に ubuntu イメージを削除しましょう。

なお、最初は Docker イメージと Docker コンテナーの関係を理解できれば良いです。細かいコマンドのオプションについては使っていくうちに理解して覚えていけば良いでしょう。

最初に ubuntu イメージをプルします。

docker image pull ubuntu

次に ubuntu イメージを使ってコンテナーを稼働させます。対話的に実行するために -i-t のオプションを指定し、実行するプログラムとして /bin/bash を指定します。成功するとコンテナーで実行される /bin/bash のプロンプトが表示されます。

$ docker container run -i -t ubuntu /bin/bash
root@191a91f2ea82:/# 

コンテナーを稼働させたときに使ったターミナルでは、コンテナーで動作する /bin/bash コマンドのプロンプトが表示されて、Docker ホストのコマンドが実行できなくなったはずです。Docker ホストで別のターミナルを開いてコンテナーを停止させてみましょう。

停止させるコンテナーを把握するには docker container ls コマンドを実行します。

$ docker container ls
CONTAINER ID   IMAGE     COMMAND     (略) NAMES
191a91f2ea82   ubuntu    "/bin/bash" (略) nostalgic_wu

ubuntu イメージを使ったコンテナーについて、CONTAINER ID や NAME がわかります。ここでは、NAME からコンテナー名が nostalgic_wu だということがわかります。

これを停止させるために、 docker container stop コマンドを実行します。停止が成功するとコンテナー名が表示されます。

$ docker container stop nostalgic_wu
nostalgic_wu

停止させただけだとコンテナーは破棄されず、コンテナーが使用しているコンピュータリソースが残ったままになります。破棄(削除)するには docker container rm コマンドを使います。破棄が成功するとコンテナー名が表示されます。

$ docker container rm nostalgic_wu
nostalgic_wu

使用しているコンテナーがない場合は、Docker ホストにキャッシュされている Docker イメージを docker image rm コマンドで削除することができます。ubuntu イメージを削除すると、次のような結果となります。

$ docker image rm ubuntu
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:e3f92abc0967a6c19d0dfa2d55838833e947b9d74edbcb0113e48535ad4be12a
Deleted: sha256:17c0145030df106e60e5d99149d69810db23b869ff0d3c9d236279a5a7bbb6b3
Deleted: sha256:42d3f8788282c6e48bac7236609753b240db353465dc55cb77c21f2391720dd9

lazydocker の利用

VS Code が使えない環境で、ターミナルで Docker の管理をしたい場合は、lazydocker コマンドを使うことを検討してみるとよいでしょう。これは、https://github.com/jesseduffield/lazydocker で開発がされている MIT License の OSS です。

/images/20240630_docker/lazydocker.png
lazydocker

ここでは、Ubuntu/WSL Ubuntu へインストールする方法について説明します。

Homebrew を使ったインストール

Homebrew を使ってインストールできるので、まずは、これをインストールします。
https://docs.brew.sh/Homebrew-on-Linux#requirements に必要な要件についての説明があります。この説明に従って、次のようなインストールスクリプト install_homebrew.sh を用意します。

install_homebrew.sh
#!/bin/sh
INSTALL_SCRIPT_URL=https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh
apt-get -y install build-essential procps curl file git
/bin/bash -c "$(curl -fsSL ${INSTALL_SCRIPT_URL})"

管理者権限が必要なので sudo コマンドを使ってインストールします。

sudo sh ./install_homebrew.sh

これで /home/linuxbrew 配下に brew コマンドがインストールされます。

これを使えるようにするために、${HOME}/.bashrc に次の内容を追加します。

test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)"
test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bashrc

用意ができたら、Ubuntu/WSL Ubuntu のターミナルについて、exit コマンドを使って終了します。それから、Ubuntu なら新しいターミナルアプリを開き、WSL Ubuntu なら再度ターミナルへアタッチしなおします。それから、brew コマンドで lazydocker をインストールします。

brew install jesseduffield/lazydocker/lazydocker

これで、lazydocker コマンドが使えるようになります。

lazydocker

${HOME}/.local/bin/lazydocker へインストール

Ubuntu/WSL Ubuntu では、Homebrew を使わずに lazydocker をインストールすることもできます。その場合は、次のコマンドを実行します。

REPO_MASTER_URL=https://raw.githubusercontent.com/jesseduffield/lazydocker/master
curl ${REPO_MASTER_URL}/scripts/install_update_linux.sh | bash

この install_update_linux.sh スクリプトを使うと、~/.local/bin/lazydockerlazydocker コマンドが用意されます。

Docker 版 lazydocker

lazydocker コマンドを Docker で動作させることもできます。docker run コマンドで実行するのが普通かもしれませんが、筆者は使い方を覚えておくことができないことが多いので、次のように Docker Compose 用の compose.yaml ファイルを用意して使えるようにしています。

lazydocker/
├── compose.yaml
└── config/
    └── config.yml

このように compose.yaml ファイルを使った参照用のディレクトリーを用意しておけば、どの Docker イメージを使うのか、その Docker イメージで指定する場合の設定ファイルのパスはどうなっていたか、といったことを簡単に確認することができます。

ここで用意する compose.yaml ファイルは次のようになります。

lazydocker/compose.yaml
name: lazydocker
services:
  lazydocker:
    image: lazyteam/lazydocker
    container_name: lazydocker
    stdin_open: true
    tty: true
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./config:/.config/jesseduffield/lazydocker

設定ファイルの config.yml については、初期値は空です。そのため、バインドマウントをしなくても良いですし、https://github.com/jesseduffield/lazydocker/blob/master/docs/Config.md を参考にして作成しても良いです。

実行するには、docker compose run コマンドを使います。

cd lazydocker
docker compose run --rm lazydocker

終了するには Esc キーを入力します。また、終了後に使用したリソースを完全に削除するには docker compose down を実行します。

docker compose down

もし docker コマンドに慣れているなら、それを使って実行しても良いでしょう。最初にカレントディレクトリーを lazydocker にします。

cd lazydocker

次のように実行します。

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  lazyteam/lazydocker

設定を指定したい場合は、次のように config/config.yml をバインドマウントしてコマンド実行します。

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd)/config:/.config/jesseduffield/lazydocker \
  lazyteam/lazydocker

Discussion