EC2(Linux)上でdockerコンテナを起動してみる

2021/9/18

(最終更新: 2022/9/17

アイキャッチ

はじめに

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の仕組みイメージ dockerの仕組みイメージ

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:wqEnterの順に押す。

Viエディタに慣れていない場合、VSCodeの拡張機能を使ってSSH接続するとやりやすいです。

参考:SSHアクセスした先のファイルをVSCodeで編集する方法メモ - エンジニアを目指す日常ブログ

ファイルに記載する中身は以下とします。

Dockerfile
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の知識は浅いためこれくらいにしておきます)

srcの作成

先ほど./srcフォルダの中身をコンテナの/usr/share/nginx/htmlにコピーする処理を書いたので、srcフォルダとその中身を作成しておきます。

$ mkdir src
$ cd src
$ touch index.html
$ vi index.html

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を入力する。

Webサイトを表示することができました。 サイトを表示できた

表示できない場合は、AWSマネジメントコンソールから、EC2の権限を確認しましょう。 設定されているセキュリティグループのインバウンドルールが、ポート80のアクセスを許可しているか確認します。

ポート80が許可されていない場合は、許可する設定にします。今回は練習なので、誰からでもアクセスできるようにしてしまいました。

セキュリティグループ設定

※ローカル開発環境の場合はlocalhost:8080にアクセスすればOKです。

Dockerfileの中身が実行されるタイミング

Dockerfileの中身が実行されるタイミングは、

dockerイメージをビルドするとき

となります。

試しに、index.htmlの中身を書き換えてみましょう。

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



個別連絡はこちらへ→Twitterお問い合わせ

プロフィール

プロフィールイメージ

はち子

事業会社のシステム部門に異動して4年目の会社員。システム企画/要件定義/システムアーキテクチャ等。

Twitter→@bun_sugi

過去の記事について

はてなブログに掲載の記事(主にプログラミングメモ)についてはこちらに掲載しております。(本ブログに移行中)

タグ一覧

関連記事

Copyright© 2022, エンジニアを目指す日常ブログ

お問い合わせ|プライバシーポリシー