はじめに
私は今までDockerについて、「なんか同じ開発環境をチームで共有できるよ~」という漠然のイメージのみ持っていたため、まあいらんやろ!って興味ゼロでした…。しかし、どうやらDocker使うの当たり前YO!みたいな風潮にやっと気づいたので、完全初心者がゼロから学んだことを書き連ねていきます。
Dockerとは?
Dockerとは、「コンテナ」と呼ばれる軽量な仮想環境を提供してくれるソフトウェアです。Dockerを使ってアプリやWeb開発の環境を構築すれば、他の人もDockerさえインストールすれば、まったく同じ開発環境をすぐに再現できます。
そのため、
「サービスのバージョンが人によって違ってて動かない!」
「あの人の環境だとバグが出ないのに、自分だけ出る!」
みたいなチーム開発でありがちな問題を減らすことができます。
Dockerの特徴~コンテナ型仮想化~
従来の仮想化では、「仮想マシン(VM)」という単位で環境を作っていました。
これは、OSごと丸ごと仮想化する方法で、たとえばWindowsで言えば「Hyper-V」などがこれにあたります。この方法は、仮想マシンごとに
- 独立したOS(UbuntuやWindows)を1つずつ用意して
- メモリやディスクもそのOSのぶんだけ用意して
- 起動も遅く、リソース消費も大きい
というデメリットがありました。
🐳 そこでDockerの登場!
Dockerは、「OSまるごと」ではなく、必要なアプリとライブラリだけを個別にまとめて
それをコンテナという単位で※ ホストOSの上で動かす仕組みです。
具体的には、
- DockerコンテナはOSの“カーネル(中核)”だけをホストOSと共有し、
- 各コンテナごとにアプリやライブラリ、設定ファイルを個別に持って、
- あたかも独立したLinuxのように振る舞います.
ホストOS = PCを直接動かしてるOS(Windows/macOS/Linux)。
ただしDockerはLinuxのカーネル(中枢の部分)を使って動く仕組みなので、Windowsでは「WSL2」っていうLinuxの仮想環境をこっそり?起動して、その中でDockerが動いてる!なので、ホストOSで動くってことは、このwindowsの上で動いているのか。。!ってわけじゃないと思ってます!たぶん!
もう一つのメリットが、クラウドに環境を移行しやすい!です。
クラウド(AWS, Azureなど)で運用したい!って時に、クラウド各社はDockerコンテナをそのまま使える仕組みを標準で持っているので、ローカルで作ったDockerイメージをそのままアップロードすればよし!わざわざクラウド上に環境構築をし直す手間がほとんど省けます。
Dockerを管理するためのツール
Dockerでは基本的に一つのコンテナに一つのサービスのみを動かすのが望ましいとされているそうです。そのため、Webサービスに適用した場合、Webサーバー、リバースプロキシ、データベースサーバーなどなど、たくさんのサービス同士が依存した構成になっていることがほとんど。なので、複数のコンテナを管理・運用する必要があるのですが、このような複数コンテナをデプロイする際のスケジューリングを自動化したり、ネットワーク接続されたクラスタ全体の構成管理を自動化する機能を、オーケストレーションと呼びます。
このDockerのオーケストレーションを提供するツールにてデファクトスタンダード(一般的?主流?)なのが、Kubernets(クバネティス)です。
このKubernetsも学びたい!って思ったのですが、どうやら学習コストがだいぶ大きいみたい。。
でも、クラウドサービス独自のオーケストレーションがあるので(AWSのECS等)それでいいや!
はじめてコンテナを作ってみる。
Dockerのインストール方法は、YoutubeやQiitaで色んな人がめちゃくちゃわかりやすく教えてくれているのでそれを見てください!
やることの内容
- Dockerが起動できるか確認する、Docker公式コンテナである、Hello-worldコンテナを動かす。
1. Docker Desktopを起動!
まず私がやらかしたこととして、いきなりターミナルでコマンドを実行したら、エラーが出る…。どうやら、Docker Desktopを起動しないと、Dockerコマンドをターミナルで実行しても何も起きないようです!理由としては、Dockerのデーモンというものが動作していないから!
2. ターミナルで"docker run hello-world"を実行
docker run hello-world
上記のコマンドを実行すると、以下の流れでコンテナが作成されます。
① デーモンがローカルに hello-world イメージがあるか確認
hello-world は「軽量な動作確認用イメージ」で、まだ無ければ次のステップへ。
② 無ければ レジストリ からダウンロード(pull)
hello-world イメージがレジストリ(イメージを保存・配信するためのシステム)にあるのを確認し、自動で取得してきます。
※ Dockerレジストリをクラウド上で公開しているサービス名が「Docker Hub」だと私は解釈しています。レジストリサービスは他にも複数ありますが、hello-world イメージはデフォルトでは Docker Hub にあるため、通常そこから取得されます。(解釈が間違っていたらすみません泣)
③ イメージからコンテナを作成(create)+起動(start)
イメージをもとに「一時的なコンテナ(プロセス)」を作成します。つまり、hello-world の中に書かれた 実行処理がスタートします。
④ コンテナの処理:画面にメッセージを表示
起動出来たら、Hello from Docker!と表示されると思います。
Dockerfileってなに?
いきなり例に入りますが、従来の方法でPythonでデータ分析するための環境構築をしたいとなったとき、以下のような作業が必要になります。
- Python本体のインストール(例:Python 3.11)
- 必要なパッケージ(pandas, numpyなど)のインストール
- 作業用ディレクトリやファイルの作成
しかし、Dockerではこれらの環境をイメージとしてまとめておくことができます。Dockerでイメージからコンテナを作成する方法は大きく分けて2つある?と思います!
1. docker commit コマンドを使う方法
この方法では、以下の手順で環境を作成します。
- ベースとなるイメージ(例:
python:3.11-slim)を取得 - そのイメージからコンテナを起動
- コンテナ内で、
pip install pandasなどのコマンドで必要な環境を構築 - 完了した状態のコンテナを
docker commitで新しいイメージとして保存 - その新しいイメージをもとにコンテナを再利用
この方法は一人で軽く作業したいときに便利ですが、
- 手順がスクリプトとして残らず再現しにくい
- バージョン管理がしにくい(変更の追跡が難しい)
- チーム開発やCI/CDとの相性が悪い
といったデメリットがあります。
2. Dockerfile を使う方法(一般的)
もう一つは、Dockerfile というファイルに環境構築の手順を明示的に書く方法です。
FROM python:3.11-slim
WORKDIR /app
RUN pip install pandas numpy
COPY . .
CMD ["python"]
このDockerfileを docker build で実行すれば、自動でイメージが作成されます。
GitHubなどにDockerfileを保存すれば、どのようにイメージが作られたのかが一目瞭然で、変更履歴も追跡できます。
そのため、チーム開発や本番環境ではこの方法が一般的?みたいです。
docker-composeとは?
Dockerでは、1つのDockerfileから1つのイメージを作成し、それを使って1つのコンテナを立ち上げるのが基本です。
しかし、Webアプリ開発では一般的に、
- フロントエンド(例:Next.js)
- バックエンド(例:DjangoやNode.js)
- データベース(例:PostgreSQLやMySQL)
など複数のサービスが連携して動作する必要があります。
このような場合、それぞれのサービス用にDockerfileを書き、個別に docker build や docker run をするのは非常に手間です。
そこで登場するのが docker-compose です!
💡 docker-compose の役割
- 複数のコンテナ構成を 1つの docker-compose.yml ファイルにまとめて定義できる
- docker-compose up を実行するだけで、定義された全てのサービスを一括でビルド&起動できる
- 複数コンテナ間のネットワークや環境変数の設定も簡単にできる
私がDockerについて疑問に思ったこと
Q. Dockerのコンテナ内で作ったファイルはどうなるの?
A. コンテナ内で作ったファイルは、原則「そのコンテナの中だけ」に存在し、ホストには残らない?
そのために、docker-compose.ymlにて、volumeというのがある。
Q. GitHubでのファイル共有ってどうするの?
Q. Dockerfileってどこまで書くの?開発環境を整えるって言っても、プログラムをダウンロードする+簡易的にディレクトリ構造を決定しておくのかな?
A. 基本は「動かすのに必要な最低限の環境構築だけ」を書く。
startproject などの「コードの初期生成」はgitHubで共有するからいいの
Q. どうやってDockerイメージって共有するの?Docker Hub?それともGitHub?
A. イメージは Docker Hubで共有する のが一般的。ただし、DockerfileをGitHubで共有する方法が主流!
自分で進めててぶち当たった壁
Next.jsのdocker-compose upがムズイ。
どうやら、Next.jsをコンテナ化するには、すでにディレクトリ上にindex.jsとかsrcフォルダ?がないとダメ見たい。なので、ローカルで環境構築をして、npx create-next-app~ってコマンドを打って、初期フォルダを作るのが普通見たい。なので、Dockerだけあればローカルに環境構築しなくていい!っていうわけではないかも。(Dockerだけで環境構築できる方法もあります!)