はじめに
docker環境を構築し、コンテナを立ち上げて、Webサイトを表示してみます。
実行環境のサーバは、AWSのEC2(Linux)を利用します。(ローカル開発環境でも問題ありません。)
前提
- AWSマネジメントコンソールにアクセスできること。
- IAMユーザに対し、必要なAWSサービスの利用を許可するIAMロールが紐づいていること。
- LinuxOSベースのEC2インスタンス(Amazon Linux 2)にSSHアクセスしていること。
EC2インスタンスの起動とSSHアクセスの方法 : https://tomiko0404.hatenablog.com/entry/2021/09/14/aws-ec2start
dockerコンテナを立ち上げるまでに必要なこと
簡略化すると、次の3ステップです。
- Dockerfileを作成する。
- Dockerfileに従って、dockerイメージを作成する。(
docker build
) - dockerイメージを利用して、dockerコンテナを立ち上げる。(
docker run
)
dockerをEC2にインストール
コマンドを実行しdockerをインストールします。
$ sudo amazon-linux-extras install docker -y
amazon-linux-extras
とは、ソフトウェアをamazon-linux-extras
リポジトリからインストールすることができるコマンドです。
インストールできたかどうか確認します。
$ docker version
【参考】ローカル環境の場合
amazon-linux-extras
は使えないため別のパッケージ管理コマンドでインストールします。
公式ページにインストール方法が載っています。 Install Docker Engine | Docker Documentation
パッケージ管理ソフトはLinuxディストリビューションによって変わります。ubuntuの例を示します。
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
インストールできたか確認します。
$ docker version
Client: Docker Engine - Community
Version: 20.10.18
API version: 1.41
Go version: go1.18.6
Git commit: b40c2f6
Built: Thu Sep 8 23:11:43 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
※VirtualBoxを使った仮想環境で実施しています。
(参考)ディストリビューションとは:→ディストリビューションとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
コンテナイメージ作成
コンテナを起動するためには、コンテナの設計書となるdockerイメージが必要となります。
Dockerfile
というテキストファイルに、
dockerイメージをビルドするときに実行する命令
を記載します。作業用フォルダを作成
$ mkdir docker_test
$ cd docker_test
Dockerfileを作成
ViエディタでDockerfileを編集します。
$ touch Dockerfile
$ vi Dockerfile
【参考】Viエディタの操作:書きたい内容をコピーして、ファイル内にペースト→Esc
→:
→w
→q
→Enter
の順に押す。
Viエディタに慣れていない場合、VSCodeの拡張機能を使ってSSH接続するとやりやすいです。
ファイルに記載する中身は以下とします。
FROM nginx:latest
COPY ./src /usr/share/nginx/html
ベースイメージの指定
FROM nginx:latest
の部分は、必須の記載となります。
FROM
のあとに、公開されているベースのイメージを記載します。ベースとなるイメージは、Docker Hubというdockerイメージの共有サービスから探すことになります。
今回はnginxを使うことができるイメージの最新バージョンをベースに利用するため、nginx:latest
と記載しています。
nginxとは、Apacheに並んで人気となる、Webサーバを構築するためのソフトウェアです。公式のdockerイメージについては、nginx - Official Image | Docker Hubで示されています。
(参考)
コンテナ上でNode.jsアプリを立てたい場合は >> node - Official Image | Docker Hub
ビルドするときに実行してほしい処理
Dockerfile
には、ビルド時に実行してほしい処理を記載できます。
今回は、EC2上(ビルドを実行する場所)の./src
フォルダの中身をコンテナの/usr/share/nginx/html
にコピーする処理を書いています。
なぜ/usr/share/nginx/html
にコピーするかというと、nginxをベースとしたコンテナでは、Webサーバのドキュメントルートとして/usr/share/nginx/html
が設定され、ポート80でアクセスした場合はこの配下にあるindex.html
にアクセスするという仕様があるためです。(nginx
の知識は浅いためこれくらいにしておきます)
- Dockerfileのリファレンス:Dockerfile リファレンス — Docker-docs-ja 20.10 ドキュメント
- COPYコマンドの説明:https://docs.docker.jp/engine/reference/builder.html#copy
srcの作成
先ほど./src
フォルダの中身をコンテナの/usr/share/nginx/html
にコピーする処理を書いたので、src
フォルダとその中身を作成しておきます。
$ mkdir src
$ cd src
$ touch index.html
$ vi index.html
index.html
の中身は何でもよいです。
一般的な形にしておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dockerテスト</title>
</head>
<body>
<h1>Hello world Docker test </h1>
<p>このページは、dockerでnginxサーバを立ち上げるテスト用です。</p>
</body>
</html>
dockerを起動する
docker_test
フォルダ配下に戻り、dockerの機能自体を起動します。
$ sudo service docker start
Redirecting to /bin/systemctl start docker.service
dockerイメージの作成
いよいよdocker build
コマンドでイメージを作成します。
$ sudo docker build . -t hello-world-docker-test
Sending build context to Docker daemon 3.584kB
Step 1/2 : FROM nginx:latest
---> ad4c705f24d3
Step 2/2 : COPY ./src /usr/share/nginx/html
---> 493a511a3313
Successfully built 493a511a3313
Successfully tagged hello-world-docker-test:latest
- 第一引数の
.
はどこにイメージを作るかを指定している。(カレントフォルダ) -t [イメージ名]
はイメージ名のを指定できるオプション。(今回はhello-world-docker-test
)
作成したイメージを確認する
作成したイメージを確認するために、イメージ参照コマンドをたたきます。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world-docker-test latest 493a511a3313 3 minutes ago 133MB
nginx latest ad4c705f24d3 12 months ago 133MB
コンテナを起動
dockerイメージ(設計図)を作成できたので、実際にdocker run
コマンドでコンテナを起動します。
$ sudo docker run --rm -p 80:80 hello-world-docker-test
-p 80:80
オプションは、ポートフォワーディング
の設定。EC2(docker実行場所)のポート80にアクセスすると、dockerコンテナ上のポート80で動いているアプリケーションに接続できるようになる、という意味です。--rm
の意味は、以下のとおり。デフォルトではコンテナを終了しても、コンテナのファイルシステム(の内容)を保持し続けます。そのため、デバッグはとても簡単になり(最後の状態を確認できるため)、デフォルトで全てのデータが保持されます。しかし、プロセスを短い期間だけ フォアグラウンド で動かしたとしても、これらのコンテナのファイルシステムが溜まり続ける場合があります。そうではなく、 コンテナの終了時に、自動的にコンテナをクリーンアップし、ファイルシステムを削除する には --rm フラグを追加します。 →Docker run リファレンス — Docker-docs-ja 20.10 ドキュメント
(参考) EC2ではなくローカルでやる場合
もし、docker環境構築の作業をEC2ではなく自分のローカルPC上で実施するのであれば、参考動画の通り、
$ sudo docker run --rm -p 8080:80 hello-world-docker-test
が自然です。
ローカルのポート8080(localhost:8080
)にアクセスすることで、dockerコンテナ上のポート80で動いているアプリケーションに接続できます。ポート8080というのは、テスト環境やローカル環境でよく使われるポートです。80と似ているという理由で、使われるようです。
Webサイトを確認する
自分のPCでブラウザを開き、[EC2のパブリックIPアドレス]:80
を入力する。
パブリックIPアドレスの確認方法はこちらを参照。
表示できない場合は、AWSマネジメントコンソールから、EC2の権限を確認します。 設定されているセキュリティグループのインバウンドルールが、ポート80のアクセスを許可しているか確認します。
ポート80が許可されていない場合は、許可する設定にします。今回は練習なので、誰からでもアクセスできるようにしてしまいました。
※ローカル開発環境の場合はlocalhost:8080
にアクセスすればOKです。
Dockerfileの中身が実行されるタイミング
Dockerfile
の中身が実行されるタイミングは、
dockerイメージをビルドするとき
となります。試しに、index.html
の中身を書き換えてみます。
<h1>Hello world Docker test </h1>
<p>このページは、dockerでnginxサーバを立ち上げるテスト用です。</p>
<p>編集した!!!!</p>
以下の事実がわかります。
- ファイルを保存しただけではサイトの見た目は変わらない。
sudo docker run
コマンドを再実行してもサイトの見た目は変わらない。sudo docker build
コマンドを再実行し、そのあとsudo docker run
を実行すると、サイトの見た目が変わる。
変更後のソースコードをdocker
上にコピーするCOPY
コマンドは、イメージをビルドした時に実行されるためです。
おわりに
Amazon EC2でdockerを立ち上げてみることができました。
関連記事
Amazon ECS Fargateでコンテナを起動しています。
EC2上でdocker run
を実行してEC2上にコンテナを立ち上げるのではなく、ここで作ったdockerイメージを使ってECS上でコンテナを立ち上げる記事。
https://tomiko0404.hatenablog.com/entry/2021/09/18/ECSFargate