DockerでカンタンWeb3層システム構築

# はじめに
今回は、Dockerを使ってカンタンなWeb3層システムを構築してみます。
以前の記事では手作業でサーバ構築していますが、後程紹介するDockerfileやdocker composeを使うと、ラクにシステムを構築することができます。
以前の記事

https://qiita.com/maplejava/items/aa928961f0c6289f525d

# Dockerのインストール（Ubuntu 18.04）
以前の記事を参考にDockerをインストールする。

https://qiita.com/maplejava/items/7429dfe7c8f33fa7f8eb#docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%ABubuntu-1804

# Ubuntu18.04サーバを構築してみる

ubuntuのTagは18.04にする。

https://hub.docker.com/_/ubuntu/tags

ubuntuの18.04のイメージをダウンロードし、ログインする
```
docker run -it -p 10081:80 ubuntu:18.04
```
これだけでubuntuサーバにログインができる。試しにApacheでもインストールしてみよう。

アップデート
```
apt update&&apt upgrade -y
```

apacheのインストール
```
apt install apache2
```

apache2サービスを開始
```
service apache2 start
```


ホストのIPアドレス:10081でコンテナのapache2に接続できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/a4bebb3e-f8e4-f527-af76-7f15c9eff3f6.png)

ちなみに今回のイメージの場合ubuntuにログイン後、systemctlコマンドはサポートされていない（Dockerコンテナはプロセルの隔離をするのみ。システムレベルの制御には工夫がいる）。

その代わりserviceコマンドをサポートしており、以下のようにコンテナ内のサービスを確認/起動/停止/再起動できる。
```
service apache2 status/start/stop/restart
```

# Dockerfileを使って構築してみる
上記のように毎回イメージを作って、ログインして、必要なソフトウェアをインストールして…とするのは面倒ですよね。
なので、Dockerfileというファイルに必要な設定を入れておけば、Dockerがその設定が終わった状態のイメージを作成してくれます。

Apache Dockerfile
```dockerfile
FROM ubuntu:18.04
RUN apt-get -y update && apt-get install -y apache2
CMD ["apachectl","-D","FOREGROUND"]
```

ビルド
```
docker build -t ubuntu18-apache .
```
実行
```
docker run -d -p 10082:80 ubuntu18-apache
```
参考

https://qiita.com/tnoce/items/6a066043c5d4e3a955d6

# 同じようにAP・DBサーバも構築してみる
### APサーバ
1. [warファイルの用意](https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/)（sample.war）
2. Dockerfileをつくる

```dockerfile
FROM tomcat:9.0.46
COPY sample.war $CATALINA_HOME/webapps/
```
ビルド
```
docker build -t tomcat8 *.*
```
実行
```
docker run -p 10081:8080 -d tomcat8
```

参考

https://amateur-engineer.com/docker-tomcat-deploy/

### DBサーバ
Dockerfileに「env MYSQL_ROOT_PASSWORD」を記載するか、コンテナ起動時に`-e MYSQL_ROOT_PASSWORD=`を指定しないとコンテナが起動できない。

Dockerfileを作る
```dockerfile
FROM mysql:8.0.30
ENV MYSQL_ROOT_PASSWORD=password
```
ビルド
```
docker build -t mysql8 .
```
実行
```
docker run -p 10083:3306 -d mysql8
```

mysqlがインストールされているサーバから以下のコマンドで接続できる。
```
mysql -u root -p -h 10.10.100.24 -P 10038
```

参考

https://ponsanlabo.com/create-mysqldockerimage-from-dockerfile/

# Docker Composeから作ってみよう
Docker Composeを使用すると、マウント先のvolumeやネットワークの情報、複数コンテナの情報をひとまとめに定義できる。

# Docker Composeのインストール（Ubuntu）
```
apt install docker-compose
```
確認
```
docker-compose —version
```

# Docker ComposeでWeb3層システム構築

docker-compose.yml
```docker
version: '3'
services:
  apache01:
    build: ./apache
    image: apache-image
    container_name: apache1
    ports:
      - "80:80"
  
  tomcat01:
    build: ./tomcat
    image: tomcat-image
    container_name: tomcat1
    depends_on:
      - apache01
    expose:
      - "8009"
  
  mysql01:
    build: ./mysql
    image: mysql-image
    container_name: mysql1
    depends_on:
      - tomcat01
    expose:
      - "3306"
```
### Webサーバ

Dockerfile
```dockerfile
FROM ubuntu:18.04
RUN apt-get -y update && apt-get install -y apache2
COPY fqdn.conf /etc/apache2/conf-available/fqdn.conf
RUN chown root:root /etc/apache2/conf-available/fqdn.conf && chmod 644 /etc/apache2/conf-available/fqdn.conf
RUN a2enconf fqdn
RUN a2enmod proxy
RUN a2enmod proxy_ajp
COPY apache2.conf /etc/apache2/apache2.conf
CMD ["apachectl","-D","FOREGROUND"]
```
apache2.conf（以下を追記）
```conf
ServerSignature Off

ProxyPass / ajp://tomcat01:8009/
ProxyPassReverse / ajp://tomcat01:8009/
```

### APサーバ

Dockerfile
```
FROM tomcat:8.5.81
COPY sample.war $CATALINA_HOME/webapps/
COPY server.xml /usr/local/tomcat/conf/server.xml
```
server.xml
```xml
//↓追記
<Connector protocol="AJP/1.3"
port="8009"
address="0.0.0.0"
redirectPort="8443"
secretRequired="false" />
```

### DBサーバ
/docker-entrypoint-initdb.d/に.shや.sqlを配置すると公式のmysqlコンテナはそれをコンテナ起動時に実行してくれる。

Dockerfile
```dockerfile
FROM mysql:8.0.30
ENV MYSQL_ROOT_PASSWORD=password
EXPOSE 3306
COPY sampledata.sql /tmp/sampledata.sql
COPY create_user.sql /docker-entrypoint-initdb.d/create_user.sql
COPY import_data.sh /docker-entrypoint-initdb.d/import_data.sh
```
※sampledata.sqlは初期データ投入用のSQLコマンド。

create_user.sql
```sql
create database sampledatabase;
create user user01@'%' identified by 'password';
grant all privileges on user01.* to user01@'%';
```
import_data.sh
```sh
mysql -u root -ppassword sampledatabase < /tmp/sampledata.sql
```


# （参考）Docker Composeでよく使うコマンド
（docker-compose.ymlファイルがカレントにある状態で）docker-composeで指定したすべてのサービスをビルド

```
docker-compose build
```

イメージができたか確認
```
docker images
```
コンテナ起動
```
docker-compose up -d
```
起動したコンテナの確認
```
docker-compose ps
```
イメージもコンテナも全て削除
```
docker-compose down --rmi all
```
作成されたnetworkを一覧で表示する
```
docker network ls
```
指定したnetworkの構成の詳細を確認する
```
docker network inspect [network名]
```

# 参考
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1#docker-composeを動かしてみる

https://www.wantanblog.com/entry/2020/04/25/164724

https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a