コンテナとGitを利用したWebシステム開発の効率化

## はじめに
システムやアプリの開発をする際、Github上にリポジトリを作ってそこでソース管理することが多いが、実行環境がこれらのソースを直接的に見ていなかったり、開発環境はローカルで立てたりするため、手元では動いたが本番環境にアップロードすると失敗といった事が頻繁に起こっていた。
今回、ソースコードをGithub上に置き、そのソースコードを参照する様なWebサーバーコンテナができないかを試してみたので、本記事ではその内容をまとめる。

## 実行環境
【Docker導入環境】
　　・Ubuntu20.04 LTS（GCP上）
　　・docker19.03.13

【コンテナ環境】
　　・Image Ubuntu:20.04
　　・Apache2.4.41 


## 試してみる事
docker上に2つのWebサーバー用コンテナを作成して、1つを本番用、もう1つを開発用とする。
本番用のコンテナはビルドする度に、Githubリポジトリの`main`ブランチからアプリコードをCloneする様にし、
開発用のコンテナは`dev`ブランチからアプリコードをCloneするように`Dockerfile`を作成してみる。


## 手順

１．環境準備
２．Github上にリポジトリを作成
３．Apacheを起動させるまでのDockerfileを作成
４．Github上のコードを取得するDockerfileに修正

## １．環境の準備

**GCP上にVMインスタンスを作成**
　※イメージはUbuntu20.4 LTS

**dockerのインストール**
　※[【Dockerコンテナ内のUbuntuではsystemctlは使えない】](https://qiita.com/smiler5617/items/2a33d1aba0174480e9d3)の手順１を参考に。


## ２．Github上にリポジトリを作成

Github上で以下を実施する。

**■Public用のリポジトリを作成**　
　※手順４のDockerfileの内容は、Publicリポジトリからクローンすることを前提としている。

**■作成したリポジトリ内の直下に『App』フォルダを作成**

**■『App』フォルダ内にindex.htmlを作成**
　※中身は適当に記載

**■開発用のブランチを切る**
　※手順４ではブランチ名は `main（本番用）` と `dev（開発用）` を前提としている。

## ３．Apacheを起動させるまでのDockerfileを作成

**DockerFile を作成する**

```
$ sudo nano ./Dockerfile
```
※最初『DockerFile』というファイルを作成したが、"F" が大文字だったためビルドに失敗した。


```dockerfile:Dockerfile

# ベースイメージの取得
FROM ubuntu:20.04

# メタデータの登録
LABEL maintainer="作成者の氏名"
LABEL version="1.0"
LABEL description="DockerFileのテスト Apacheサーバー起動"

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2

# ポート開放
EXPOSE 80

CMD ["apachectl", "-D", "FOREGROUND"]
```

**ビルドしてイメージを作成**

```shell:
$ docker image build -t websys:production ./
```
　※今回、DockerFileはカレントディレクトリに作成しているためパス部分が `./` となっている。

**イメージの確認**

```shell:
$ docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
websys              production          5e35969b988e        15 seconds ago      67.3MB
ubuntu              18.10               9dc19675e327        16 months ago       67.3MB
```

**上記のイメージを使ってコンテナ作成**

```
$ docker container run -it -d -p 8080:80 --name ap1_server websys:production
```

以下のURLにアクセスして初期画面が開かれればOK!

`http://[VMの外部IP(グローバルIPアドレス)]:8080/`



## ４．Github上のコードを取得するDockerfileに作り直し

Github上に`main`ブランチと`dev`ブランチがある前提で、本番環境は`main`ブランチからソースコードをクローンする様にし、開発環境は`dev`ブランチからソースをクローンする様に作り直し。

本番環境、開発環境はクローン対象が違うため、それぞれDockerfileを用意する。

**まずはディレクトリ作成**

```
$ sudo mkdir ./main
$ sudo mkdir ./dev
```

**ビルド時に反映させるサイトコンフィグの情報を作成**

■本番環境用

```
$ sudo nano ./main/main_site.conf
```

```apache:main_site.conf
# Githubのリポジトリの階層構想により、DocumentoRootの場所は調整。

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/main/App
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

■開発環境用

```
$ sudo nano ./dev/dev_site.conf
```

```apache:dev_site.conf
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/dev/App
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

**DockerFile を作成し直し**
　※手順３のDockerfileは破棄してしまってOK。

■本番環境用のDockerfileを作成

```
$ sudo nano ./main/Dockerfile
```

```dockerfile:Dockerfile
# ベースイメージの取得
FROM ubuntu:20.04

# メタデータの登録
LABEL maintainer="作成者の氏名"
LABEL version="2.0"
LABEL description="DockerFileのテスト Apacheサーバー起動"

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2
RUN apt install -y git

# 本番環境用のサイト構築（この部分が開発環境とは異なる！）
COPY ./main_site.conf /etc/apache2/sites-available/
RUN git clone --depth 1 -b main https://github.com/Smiler5617/test_websys.git /var/www/html/main
RUN a2dissite 000-default
RUN a2ensite main_site

# ポート開放
EXPOSE 80

CMD ["apachectl", "-D", "FOREGROUND"]
```

■開発環境用のDockerfileを作成

```
$ sudo nano ./dev/Dockerfile
```

```dockerfile:Dockerfile
# ベースイメージの取得
FROM ubuntu:20.04

# メタデータの登録
LABEL maintainer="作成者の氏名"
LABEL version="2.0"
LABEL description="DockerFileのテスト Apacheサーバー起動"

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2
RUN apt install -y git

# 開発環境用のサイト構築（この部分が本番環境とは異なる！）
COPY ./dev_site.conf /etc/apache2/sites-available/
RUN git clone --depth 1 -b dev https://github.com/Smiler5617/test_websys.git /var/www/html/dev
RUN a2dissite 000-default
RUN a2ensite dev_site

# ポート開放
EXPOSE 80

CMD ["apachectl", "-D", "FOREGROUND"]
```

**それぞれのDockerfileをビルド**

```
$ docker image build -t websys:main ./main/
$ docker image build -t websys:dev ./dev/
```

**イメージの確認**

```shell:
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
websys              dev                 cee2d11ec02f        37 seconds ago      264MB
websys              main                7ac716953021        6 minutes ago       264MB
ubuntu              20.04               d70eaf7277ea        3 weeks ago         72.9MB
```

**イメージよりコンテナ作成**
　※ポートのマッピングは本番環境と開発環境で変える。

```
$ docker container run -it -d -p 8080:80 --name ap_server websys:main
$ docker container run -it -d -p 8081:80 --name dev_ap_server websys:dev
```

**ちゃんと起動できているか確認**
　本番環境：`http://[VMの外部IP(グローバルIPアドレス)]:8080/`
　開発環境：`http://[VMの外部IP(グローバルIPアドレス)]:8081/`
　

**試しに`dev`ブランチでindex.htmlに変更を加えてimageを作り直したら、ちゃんと反映されているので今回やってみたかった事はできた。**
　※Dockerfileの`RUN`コマンドの中で`git clone`の記述をしているので、イメージの作成タイミングでないとクローンをし直せない。


## おまけ

上記にも記載した通り、ちょっとしたコードの修正でもイメージを作り直す必要があるので、ここら辺をもう少し簡易にできないのか試してみた。

方法としては`startup.sh` を作成して、そこの中で『git clone』と『Apacheの起動』をさせる命令を書く。そしてDokcerfileの`CMD`コマンドでは`startup.sh`を実行させるだけ。

**`startup.sh`の作成**

```shell:（本番環境用）
$ sudo nano ./main/startup.sh
```

```sh:startup.sh（本番環境用）
git clone --depth 1 -b main https://github.com/Smiler5617/test_websys.git /var/www/html/main
apachectl -D FOREGROUND
```


```shell:（開発環境用）
$ sudo nano ./dev/startup.sh
```

```sh:startup.sh（開発環境用）
git clone --depth 1 -b dev https://github.com/Smiler5617/test_websys.git /var/www/html/dev
apachectl -D FOREGROUND
```

**Dockerfileの作成**

```dockerfile:Dockerfile（本番環境用）
# ベースイメージの取得
FROM ubuntu:20.04

# メタデータの登録
LABEL maintainer="作成者の氏名"
LABEL version="3.0"
LABEL description="DockerFileのテスト Apacheサーバー起動"

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2
RUN apt install -y git

# 必要ファイルを入れる
COPY ./main_site.conf /etc/apache2/sites-available/
COPY ./startup.sh /etc/apache2/

# デフォルトサイトからの切り替え
RUN a2dissite 000-default
RUN a2ensite main_site

# ポート開放
EXPOSE 80

# イメージからコンテナを作成するタイミングでシェルを実行
CMD ["bash", "/etc/apache2/startup.sh "]
```

```dockerfile:Dockerfile（開発環境用）
# ベースイメージの取得
FROM ubuntu:20.04

# メタデータの登録
LABEL maintainer="作成者の氏名"
LABEL version="3.0"
LABEL description="DockerFileのテスト Apacheサーバー起動"

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2
RUN apt install -y git

# 必要ファイルを入れる
COPY ./dev_site.conf /etc/apache2/sites-available/
COPY ./startup.sh /etc/apache2/

# デフォルトサイトからの切り替え
RUN a2dissite 000-default
RUN a2ensite dev_site

# ポート開放
EXPOSE 80

# イメージからコンテナを作成するタイミングでシェルを実行
CMD ["bash", "/etc/apache2/startup.sh "]
```

**ビルドしてイメージ作成**

```
$ docker image build -t websys:main ./main/
$ docker image build -t websys:dev ./dev/
```

**イメージよりコンテナ作成**

```
$ docker container run -it -d -p 8080:80 --name ap_server websys:main
$ docker container run -it -d -p 8081:80 --name dev_ap_server websys:dev
```


**この改良により、わざわざイメージから作り直さずにコンテナだけ作成し直せばソースコードの更新ができるようになった。**

**以上！**


## 追伸
その後`docker-compose`も使ってみたので、その時の内容もメモとして残しています。
　[【docker-composeとGitを利用したWebシステム開発の効率化】](https://qiita.com/smiler5617/items/320b3e8d2390c16ac747)