DockerでNginxコンテナ構築

# 前回の振り返り
前回はDockerの基礎を整理して、特に重要な概念「イメージ」「Dockerfile」「Docker Compose」について説明しました。

前回の記事

https://qiita.com/miyamon_key/items/fd18ca39ca5730aa161d

今回はこの学んだ知識を定着させるために簡易構築をしてみます。

# Dockerをローカル環境にインストール
今回はローカルPC（普段利用しているノートPC）の中にコンテナを構築するので
Dockerで構築をする為の環境を整えます。

私の環境情報は以下
- PC:windows 11
- Docker Desktop:4.33.1
- Terminal:VScodeのGit bash
- Docker for windowsをインストール

https://docs.docker.com/desktop/windows/install/

ローカルPC内でコンテナを構築するにはDocker for windows(or mac)をインストールが必要です。
Windows 用 Docker デスクトップ – x86_64をダウンロードし「Docker Desktop Installer.exe」インストーラーを実行します。
インストールが完了したらTeminalでDockerのコマンドを実行してみます。
`docker version`というdockerのversion情報のコマンドを実行してみました。
```
$ docker version
Client:
 Version:           27.1.1
 API version:       1.46
 Go version:        go1.21.12
 Git commit:        6312585
 Built:             Tue Jul 23 19:57:57 2024
 OS/Arch:           windows/amd64
 Context:           desktop-linux
Server: Docker Desktop 4.33.1 (161083)
 Engine:
  Version:          27.1.1
  API version:      1.46 (minimum version 1.24)
  Go version:       go1.21.12
  Git commit:       cc13f95
  Built:            Tue Jul 23 19:57:19 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.19
  GitCommit:        2bf793ef6dc9a18e00cb12efb64355c2c9d5eb41
```

その他にも`docker` と入力してtab補完してみると以下の様にインストール前では利用出来なかったコマンドが利用可能になったことが分かります。

```
$ docker
docker                           docker-compose                   docker-credential-desktop.exe    docker-credential-wincred.exe
docker.exe                       docker-compose.exe               docker-credential-ecr-login.exe  docker-index.exe
```

# Docker構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/9e86d9b4-e710-07d3-99b2-b40a349c29cc.png)

上は前回も利用した図ですが、重要になるので改めてこちらにも置きます。
これを頭に入れた状態でディレクトリ構成を作っていきます。

# ディレクトリ構成
Dockerはディレクトリ構成（ファイルをどこに置くか）が重要です。
以下のように配置しました。
```
├─docker-test
  ├─docker-compose.yml
  │
  └─nginx
      ├─Dockerfile
```
## <ディレクトリ構成解説>
- docker-testというディレクトリ配下に
    - docker-compose.ymlファイルを作成
    - nginxディレクトリを作成
- nginxディレクトリ配下に
    - Dockerfileを作成
nginxディレクトリの中にはnginxコンテナを構築する為のファイルを管理しやすくするために個別ディレクトリを作成しました。
docker-compose.ymlのディレクトリ指定の書き方次第なので正解は無いのですが、私は1コンテナにつき1ディレクトリを作成する方法がやりやすいです。

- Dockerfileの中身は以下とします。
```
FROM nginx:1.25.3-alpine3.18
 
# timezone setting
RUN apk --update add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata && \
    rm -rf /var/cache/apk/*
 
# install packages
RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache \
    bash \
    nginx \
    sudo \
    tzdata \
    vim
 
EXPOSE 80
```
## <ファイル構成解説>
- FROM
    - Dockerhubで探したイメージを指定しています。
- RUN
    - コンテナ内で実行されるコマンドを書いています。
- EXPOSE
    - 公開するコンテナのポートを指定しています。(httpでアクセスできるよう80を指定)

- docker-compose.ymlは以下とします。
```
services:
  nginx:
    container_name: nginx
    build: ./nginx/
    image: nginx
    ports:
      - '80:80'

```

- services
    -Docker-Composeでは、アプリケーションを動かすための各要素をServiceと読んでいます。
    -今回nginxというサービス(コンテナ)を1つ構築する為、servicesの中にnginx:を入れ子にしています。
- container_name
    - コンテナ名を定義しています。
- build
    - 参照させたいDockerfileのあるディレクトリを指定しています。
    - 今回はnginx配下のDockerfileを利用したい為./nginx/を指定しています。
- image
    - イメージ名を指定しています。
    - 実際のイメージの指定はDockerfileで指定しているので、ここでは名前だけを定義しています。
- ports
    - ローカルとコンテナのポートマッピングを定義しています。
    - 今回はローカルPCの80とコンテナポート80をマッピングさせています。

# イメージをbuild

最低限Dockerコンテナを構築する準備が出来たので実行していきます。
まずはイメージをbuildさせます。イメージを作成することをbuildさせると言います。
buildにはdocker-compose buildコマンドを利用します。

```
$ docker-compose build <Log省略> 
=> [nginx] exporting to image
```

# buildしたイメージを使用してコンテナを起動
コンテナをデプロイするにはdocker-compose upコマンドを利用します。-dオプションを付け加えることでバックグラウンドでコンテナを起動してくれるので、続けてターミナル上から操作できます。

```

$ docker-compose up -d
[+] Running 2/2
 ✔ Network docker-test_default  Created                                                                                        0.1s 
 ✔ Container nginx              Started
```

# コンテナ起動確認
docker psコマンドでdockerが起動ステータスを確認できます。「STATUS」が「Up」になっていることから起動されていることが確認できます。

```
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS                NAMES
ed3f047398ea   nginx     "/docker-entrypoint.…"   33 minutes ago   Up 33 minutes   0.0.0.0:80->80/tcp   nginx
```

# コンテナにログイン
起動したコンテナにログインするにはdocker exec コマンドを利用します。[docker exec -it <コンテナ名> bash]が書式となり、Dockerfileで私はnginxとコンテナ名を定義したので-itの後はnginxとしています。-itのオプションは-i（interactive）と-t（tty）を組み合わせたものでコンテナ内で対話的なシェルを使えるようになります。

```
$ docker exec -it nginx bash
ed3f047398ea:/#
```

# 構築したNginxに実際にブラウザからアクセス
Nginxはwebサーバなのでブラウザからもアクセステストをします。今回はconfファイルをオリジナルで作成していないので、アクセス成功すればデフォルトの画面が表示されます。今回80ポートを解放して、ローカルポート80とコンテナポート80をマッピングさせているのでhttpでアクセスします。hostsで名前解決の設定をしていなければドメインはlocalhostでアクセス出来ます。
ブラウザのアドレスバーに以下を実行
http://localhost

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/578a438c-55f8-fce0-0bdf-11af4b82e7b0.png)

# 最後に
このDockerfileをgitで管理して、最低限のdocker for windowsがあれば完全に同様の環境が構築出来ますので、かなり便利だと思います。
また起動時間も短いのでコンテナのメリットを簡易構築でも十分感じられました。