Virtualbox CentOS7 Dockerコンテナ上にnginxサーバーを構築してみた

## はじめに

Docker初心者のため、CentOS7 Dockerコンテナ上にnginxサーバーを構築してみました。

infracollegeで学びました。
https://infracollege.vamdemicsystem.black/linux/

CentOS7.xの7の部分がベースバージョンです。
ベースバージョンが変わると、システムの全体的なアーキテクチャや主要なパッケージのバージョンが大きく変わります。
yum updateしてもベースバージョンの7自体は変わりません。

apacheとnginxの違いを教わりました。
基本的にはapacheとnginxどちらかをサーバーに入れます。
どちらも同じWEBサーバーでデフォルトでは80と443で起動されます。
nginxはイベント駆動型でリクエストをまとめて処理をする。
apacheはプロセス駆動型でリクエストを一つづつ処理をする。
apacheよりはnginxの方が高速です

## 前提条件
CentOS7
VritualBox使用

### Dockerとは

以下のサイトにDockerについて詳しく説明してありました。
勉強になります。
https://and-engineer.com/articles/YaSPjRIAACAAkhMI


## 構成図
VirtualBoxをホストOS(自宅のWindowsPC)にインストールし、ゲストOS(CentOS7)を構築した。
ゲストOS(CentOS7)にDocker エンジンをインストールして、nginxのイメージを使用して、nginxコンテナを構築した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/671a872b-6298-6ad5-c6b9-6607ac6ce77e.png)



Dockerのコマンドは以下のサイトが勉強になりました。
基本的なコマンドがすべて記載されているため、勉強になります。
https://zenn.dev/en2enzo2/articles/95b73cacfe0eb1

## Virtualbox Dockerコンテナ構築手順
### 便利なツールをインストール
ネットワーク関連のコマンドとコマンド補完等の便利なツールをインストールしました。
```
# yum -y install vim bash-completion net-tools bind-utils
```
### yumのユーティリティパッケージがインストール
yum-config-managerコマンドを使用するため、以下のパッケージをインストールする

以下のサイトが参考になりました。
https://akamist.com/blog/archives/942
```
# yum -y install yum-utils
```
### Dockerリポジトリを登録
yum-config-managerコマンドは、以下のサイトが参考になりました。
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/sec-managing_yum_repositories
```
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
読み込んだプラグイン:fastestmirror
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo

repo saved to /etc/yum.repos.d/docker-ce.repo
```
### Dockerをインストールする
```
# yum install docker-ce
```
### Dockerを自動起動設定する
```
# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
```
### Dockerを起動した
```
# systemctl start docker
# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 土 2022-09-03 22:28:22 JST; 6s ago
     Docs: https://docs.docker.com
 Main PID: 1546 (dockerd)
    Tasks: 7
   Memory: 32.2M
   CGroup: /system.slice/docker.service
           └─1546 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

 9月 03 22:28:21 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:21.653660354+09:00" level=info msg="ccResolverWrapper: sending update to cc: {[{...dule=grpc
 9月 03 22:28:21 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:21.653665905+09:00" level=info msg="ClientConn switching balancer to \"pick_firs...dule=grpc
 9月 03 22:28:21 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:21.680344124+09:00" level=info msg="Loading containers: start."
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.278407717+09:00" level=info msg="Default bridge (docker0) is assigned with an... address"
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.365481879+09:00" level=info msg="Firewalld: interface docker0 already part of...eturning"
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.442122797+09:00" level=info msg="Loading containers: done."
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.460889558+09:00" level=info msg="Docker daemon" commit=a89b842 graphdriver(s)...=20.10.17
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.461108382+09:00" level=info msg="Daemon has completed initialization"
 9月 03 22:28:22 localhost.localdomain dockerd[1546]: time="2022-09-03T22:28:22.490495682+09:00" level=info msg="API listen on /var/run/docker.sock"
 9月 03 22:28:22 localhost.localdomain systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost ~]#
```
### nginxのプロセスを実行する
バックグランドのnginxプロセスを実行する
コンテナ名は「nginx」で-dオプションを指定しているため、バックグランドでnginxのイメージを使って起動しています。

ローカルホストがアクセスするときに使用するポート番号(8080)してアクセスすると、コンテナ内では80ポートが使用される様です。

Dockerで使用するポート番号はローカルホスト側のポート番号とDocker内で使用するポート番号の2つを設定する必要があるそうです。
以下のサイトで学びました。
https://www.distant-view.co.jp/column/3107/
```
# docker run --name nginx(コンテナ名) -d -p 8080:80 nginx(イメージ名)
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
7a6db449b51b: Pull complete
ca1981974b58: Pull complete
d4019c921e20: Pull complete
7cb804d746d4: Pull complete
e7a561826262: Pull complete
7247f6e5c182: Pull complete
Digest: sha256:b95a99feebf7797479e0c5eb5ec0bdfa5d9f504bc94da550c2f58e839ea6914f
Status: Downloaded newer image for nginx:latest
4088b7eebb067303a1660d06fa880594cb73034306aad1ca00d91a13e8ec6458
```
### コンテナを一覧表示
先程起動したnginxのDockerが動いていることを確認
```
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                                   NAMES
4088b7eebb06   nginx     "/docker-entrypoint.…"   3 hours ago   Up 3 hours   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx
[root@localhost ~]#
```
### nginxコンテナにアクセス
レスポンス200が返ってきたため、問題なくnginxアクセス出来ています。
curl -Iは、httpのレスポンスがかえって来るコマンドです。
```
[root@localhost ~]# curl -I http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.23.1
Date: Sat, 03 Sep 2022 16:36:49 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 19 Jul 2022 14:05:27 GMT
Connection: keep-alive
ETag: "62d6ba27-267"
Accept-Ranges: bytes
```
ブラウザ経由でhttp\://192.168.0.4(dockerサーバー):8080でアクセスしたら、nginxのページが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/1ca1a07a-7d37-f861-2ee0-66ddf4ca8f52.png)

### コンテナの停止する
CONTAINER IDを確認する
```
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                                   NAMES
4088b7eebb06   nginx     "/docker-entrypoint.…"   3 hours ago   Up 3 hours   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx
[root@localhost ~]#
```
コンテナを停止した
```
# docker stop 4088b7eebb06　※コンテナIDを指定
4088b7eebb06
```
コンテナで何も表示されないことを確認した
```
# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost ~]#
```
コンテナが3分前に停止していることを確認した
詳細を確認するため、aオプションを付ける
```
# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS                     PORTS     NAMES
4088b7eebb06   nginx     "/docker-entrypoint.…"   3 hours ago   Exited (0) 2 minutes ago             nginx
```
イメージファイルをサーバーにダウンロードしてきてそれを起動しています。
dockerのイメージファイルを確認
```
# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    2b7d6430f78d   11 days ago   142MB
```
### コンテナを起動しました
```
# docker start nginx
nginx
```
再度、nginxのコンテナが起動していることを確認した
```
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS          PORTS                                   NAMES
4088b7eebb06   nginx     "/docker-entrypoint.…"   4 hours ago   Up 18 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx
```
# dockerのコンテナの中に入ってみた
以下のサイトが参考になりました。
https://zukucode.com/2019/05/docker-bash.html

仮にコンテナ内の設定ファイルを変更に備えて、コンテナの入り方を試しました。
```
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS              PORTS                                   NAMES
4088b7eebb06   nginx     "/docker-entrypoint.…"   23 hours ago   Up About a minute   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx

docker exec -it <コンテナ名> /bin/bash
プロンプトの表示がCONTAINER IDの表示になる。
# docker exec -it nginx /bin/bash
root@4088b7eebb06:/#

exitコマンドでコンテナからログアウトします。
root@4088b7eebb06:/# exit
exit
[root@localhost overlay2]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED      STATUS         PORTS     NAMES
c10cd2800f5a   debian    "bash"    5 days ago   Up 2 minutes             debian
[root@localhost overlay2]#
```
## まとめ
今回の構築でDockerの基本的なことがイメージできるようになりました。

必要なパッケージはイメージとして取得して、イメージをもとにコンテナを実行する。
コンテナを実行時に、「外部からアクセスするポート番号:コンテナのポート番号」ポートを2つ設定する必要がある

今後もDockerの勉強を継続します。