Docker CentOS7.3のコンテナにApache2.4.27をソースコードでインストール!

前に、Apache2.4.25とOpenSSL1.1.0のインストールで挫折(Apache2.4.25がOpenSSL1.1.0に対応していなかったこともあり)したので、今回は、最新のApache2.4.27でトライ。

⇩  下記サイトを参考にさせていただきました。

Apache httpd 2.4.27 + mod_http2 インストールメモ | あぱーブログ

環境は、Windows 10 Homeでございます。

DockerでCentOS7.3のコンテナを準備

まずは、Dockerの仮想マシンを起動します。 利用可能な仮想マシンの一覧は、

docker-machine ls

今回は、defaultという名前の仮想マシンを使います。

docker-machine start default

いきなりのエラー!

Starting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to create a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Found a new host-only adapter: "VirtualBox Host-Only Ethernet Adapter #2"
(default) Windows might ask for the permission to configure a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.    

『docker-machine env 仮想マシン名』を実行しろとあるので、

docker-machine env default

エラー!!!

Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "192.168.99.100:2376": x509: certificate is valid for 192.168.99.101, not 192.168.99.100
You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
Be advised that this will trigger a Docker daemon restart which might stop running containers.

『docker-machine regenerate-certs 仮想マシン名』を実行しろとあるので、

docker-machine regenerate-certs default

『y/n』と聞かれるので、『y』を入力しEnter。

Regenerate TLS machine certs?  Warning: this is irreversible. (y/n): y   
Regenerating TLS certificates                                            
Waiting for SSH to be available...                                       
Detecting the provisioner...                                             
Copying certs to the local machine directory...                          
Copying certs to the remote machine...                                   
Setting Docker configuration on the remote daemon...                     

dockerコマンドを使おうとすると、

docker ps
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.

と怒られるので、docker-machineが動いてるか確認

docker-machine active    

動いてるDockerホスト(仮想マシン)は見つからないとなるので、

No active host found    

Dockerホストに環境変数を適応させます。

eval $(docker-machine env default)    

改めて、『docker-machine active 』を実行。

docker-machine active 
default

仮想マシン名が表示されればOK。コンテナの元となるイメージをdocker-hubから取得します。

docker pull centos:latest
7b6bb4652a1b: Pull complete
Digest: sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Status: Downloaded newer image for centos:latest

取得できたか確認。

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              36540f359ca3        2 weeks ago         193MB

コンテナを作成します。『docker run -it 【REPOSITORY名】』でいけるようですが、後述でApacheとCentOS7の関係でエラーが起こるので、--privilegedオプションを付けてのコンテナの作成がおススメです。

docker run -it centos
[root@6acec634218f /]#    
docker run --privileged -d -p 80:80 --name httpd-test centos:centos7 /sbin/init    

自動的にコンテナ内にログインされるので、一旦、『Ctrl + P』『Ctrl + Q』 でコンテナから抜けます。コンテナの確認。

docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6acec634218f        centos              "/bin/bash"         16 seconds ago      Up 17 seconds                           vibrant_euclid

コンテナに再びログインします。『docker exec -it 【コンテナNAME】』でいけます。attachコマンドでもいけます。

docker exec -it vibrant_euclid

コンテナにログインできたら、CentOSのバージョンを確認してみます。

cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

とりあえず、CentOS7.3の用意までできました。

Apache2.4.27インストールに必要なライブラリのインストー

CentOS7.3に、Apache2.4.27をソースでインストールするために必要なツールをインストールしていきます。

開発ツールのインストー

yum -y groupinstall base
yum -y groupinstall development

OpenSSL 1.1.0 のインストー

OpenSSLのコンパイルに必要なツールをインストール。

yum -y install zlib-devel
yum -y install perl-core

OpenSSLのインストール。

cd /usr/local/src/
wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz
tar xvzf openssl-1.1.0f.tar.gz
cd openssl-1.1.0f/
./config --prefix=/usr/local/openssl-1.1.0f shared zlib
make depend
make
make test
make install

make testでエラーが出てるのが気になりますね。makeではエラーが出なかったので、OpenSSL1.1.0 のライブラリにパスを通しました。

echo /usr/local/openssl-1.1.0f/lib > /etc/ld.so.conf.d/openssl110f.conf
ldconfig

Nghttp2 のインストー

HTTP/2(mod_http2)のコアエンジン Nghttp2 をインストールします。 Nghttp2 が必要とするライブラリのインストー

yum -y install libev-devel c-ares-devel

Nghttp2 のダウンロード

バージョンアップが頻繫に行われているようなので、バージョンの確認をしたほうが良いようです。

https://github.com/nghttp2/nghttp2/releases/tag/v1.24.0

cd /usr/local/src/
wget https://github.com/nghttp2/nghttp2/releases/download/v1.24.0/nghttp2-1.24.0.tar.gz

Nghttp2 のインストール。環境変数 OPENSSL_CFLAGS と OPENSSL_LIBS に先ほどインストールした、OpenSSL1.1.0 のディレクトリパスを指定してコンパイルします。

tar xvzf nghttp2-1.24.0.tar.gz
cd nghttp2-1.24.0/
env OPENSSL_CFLAGS="-I/usr/local/openssl-1.1.0f/include" OPENSSL_LIBS="-L/usr/local/openssl-1.1.0f/lib -lssl -lcrypto" ./configure -enable-app
make
make install

/usr/local/lib 以下に「libnghttp2」がインストールされますので、こちらもライブラリのパスに追加しておきます。

echo /usr/local/lib > /etc/ld.so.conf.d/usr-local-lib.conf
ldconfig

 

Apache2.4.27のコンパイルに必要なツールをインストー

 

yum -y install pcre-devel
yum -y install expat-devel

Apache 2.4系をソースコードからインストールする場合は、ARPARP-util が必要になりますので、インストールしておきます。 

ARP

cd /usr/local/src/
wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-1.6.2.tar.gz
tar xvzf apr-1.6.2.tar.gz
cd apr-1.6.2/
./configure
make
make install

「./congigure」のとこで『rm: cannot remove 'libtoolT': No such file or directory config.status: executing default commands』ってのが出たのが気になるけど、GO!make。

ARP-util

cd /usr/local/src/
wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-util-1.6.0.tar.gz
tar xvzf apr-util-1.6.0.tar.gz
cd apr-util-1.6.0/
./configure --with-apr=/usr/local/apr
make
make install

 

Apache httpd 2.4.27 (mod_http2) のインストー

Apache httpdソースコードのダウンロード

cd /usr/local/src/
wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.27.tar.gz

ダウンロードしたソースコードを解凍して、ディレクトリを移動します。

tar xvzf httpd-2.4.27.tar.gz
cd httpd-2.4.27/

HTTP/2 を使うために必要なモジュール mod_http2 と mod_ssl を有効にし、--with-ssl オプションで、OpenSSL1.1.0 のディレクトリパスを指定してコンパイル&インストールします。

./configure \
--enable-http2 \
--enable-ssl \
--with-ssl=/usr/local/openssl-1.1.0f \
--enable-so \
--enable-mods-shared=all \
--enable-mpms-shared=all
 
make
make install

インストールされたか確認

/usr/local/apache2/bin/httpd -V

 

自己署名のSSLサーバー証明書の作成(HTTPS用)

httpsを利用したい場合は、SSLサーバー証明書を作成する必要があるようです。

秘密鍵の作成

openssl genrsa 2048 > server.key

CSR(証明書署名要求)の作成(入力するのは2箇所だけです)

openssl req -new -key server.key > server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.exp^Hample.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

SSLサーバー証明書の作成(有効期限10年)

openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

秘密鍵SSL証明書を移動

mv -i server.key /etc/pki/tls/private/
mv -i server.crt /etc/pki/tls/certs/

パーミッションを変更

chmod 600 /etc/pki/tls/private/server.key
chmod 600 /etc/pki/tls/certs/server.crt

CSRを削除

rm server.csr

Apache httpd の設定

オリジナルの設定ファイルをバックアップ

mv -i /usr/local/apache2/conf/httpd.conf /usr/local/apache2/conf/httpd.conf.org
mv -i /usr/local/apache2/conf/extra/httpd-ssl.conf /usr/local/apache2/conf/extra/httpd-ssl.conf.org

・設定ファイルを作成します

httpd.conf

vim /usr/local/apache2/conf/httpd.conf    

Apache httpd 2.4.27 + mod_http2 インストールメモ | あぱーブログ さんの設定を使わせてもらいましょう。

⇩  httpd.conf

https://blog.apar.jp/wp-content/uploads/2017/07/httpd_conf_20170717.txt

 

 
vim /usr/local/apache2/conf/extra/httpd-ssl.conf

https://blog.apar.jp/wp-content/uploads/2017/07/httpd_ssl_conf_20170717.txt

 

systemd サービスファイルの作成

Apache httpd 用の systemd サービスファイル(起動スクリプトのようなもの)を作成します。systemctlコマンドを自作するみたいですね。

vim /etc/systemd/system/httpd.service   

ファイルが新しく作成されて、vimエディタで開けたら、

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
 
[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/apachectl start
ExecReload=/usr/local/apache2/bin/apachectl graceful
ExecStop=/usr/local/apache2/bin/apachectl stop
 
[Install]
WantedBy=multi-user.target

をファイルに張り付けて『:wq』コマンドで保存。作成したサービスファイルを systemd に反映

systemctl daemon-reload

エラー!!!

Failed to get D-Bus connection: Operation not permitted
    

どうやら、Docker特有のエラーみたいです。

Linux - Docker上でApacheが起動できない(34023)|teratail

 

ということで、一旦、コンテナを停止してこれまでのコンテナの内容をイメージとして保存します。

Dockerの作業済みコンテナからイメージを作って移植を楽にする - Qiita

まずは、コンテナを抜け、コンテナを停止します。

exit
docker stop vibrant_euclid

確認。

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS               NAMES
6acec634218f        centos              "/bin/bash"         3 hours ago         Exited (137) 10 seconds ago                       vibrant_euclid
2a5a62b662b4        centos              "/bin/bash"         3 hours ago         Exited (0) 3 hours ago                            centos7

停止したDockerコンテナからイメージを作ります。『docker commit 【コンテナNAME】【REPOSITORY】:【TAG】』でいけます。

docker commit vibrant_euclid my_repository:httpd_test

イメージができたか確認。

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my_repository       httpd_test          dbb2513a2047        14 seconds ago      1.14GB
centos              latest              36540f359ca3        2 weeks ago         193MB

新しくイメージができたので、今までの使ってきたコンテナを削除します。コンテナの削除は、『docker rm 【コンテナID】』でいけるようです。

docker rm 6acec634218f
6acec634218f

続いて、--privilegedコマンド付きで新しくコンテナを作成します。『docker run --privileged -d -p 【外部からアクセスされるポート番号】:【コンテナ側のポート番号】 --name 【任意】【REPOSITORY】:【TAG】sbin/init』。「-d」オプションはバックグラウンドで実行とのこと。

docker run --privileged -d -p 80:80 --name "httpd" my_repository:httpd_test sbin/init

コンテナの起動確認。

docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS                NAMES
76faef5f92c8        my_repository:httpd_test   "sbin/init"         5 minutes ago       Up 5 minutes        0.0.0.0:80->80/tcp   httpd

コンテナにログイン。

docker exec -it httpd bin/bash

再度、作成したサービスファイルを systemd に反映を試みる。

systemctl daemon-reload

実行できたっぽいので、systemd に反映されているか確認。

systemctl list-unit-files | grep httpd
httpd.service disabled

起動

systemctl start httpd

ブラウザからDockerホストのIPアドレス:コンテナのポート番号(『http://192.168.99.100:80/』)にアクセスすると、コンテナ内のApacheにアクセスできます。IP確認は、

docker-machine ls
NAME               ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default            -        virtualbox   Running   tcp://192.168.99.100:2376           v17.05.0-ce
kusanagi-machine   -        virtualbox   Stopped                                       Unknown

でいけるようです。『URL』の部分の『192.168.99.100』がIPアドレスっぽいです。

f:id:ts0818:20170723163209j:plain

自動起動設定

systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /etc/systemd/system/httpd.service.

止めるときは、

systemctl stop httpd

で止まります。

 

firewalld設定

firewalldが入っていなかったので、firewalld をインストール。

firewalldは、CentOS7から採用されたデフォルトのファイアウォールです。

firewalldiptablesは共存できません。どちらかを選んでください。

ファイアウォール firewalld インストール | CentOSサーバー構築マニュアル

iptables と共存できないってところが気にはなりますが、インストール。

yum -y install firewalld
systemctl start firewalld

HTTP(80/tcp) と HTTPS(443/tcp) を開けておきます。 

firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

確認

firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcpv6-client ssh
  ports: 443/tcp 80/tcp
  protocols:
  masquerade: no
  forward-ports:
  sourceports:
  icmp-blocks:
  rich rules:

ports: 443/tcp 80/tcp』となっていればOK。Apachehttpd)の80番ポートでアクセスできるか確認

systemctl start httpd

f:id:ts0818:20170723163209j:plain

大丈夫のようです。

 

ログのローテーション設定

設定ファイルを作成します

vim /etc/logrotate.d/httpd

ファイルが開くので編集。

/usr/local/apache2/logs/*log { 
    daily 
    missingok 
    dateext 
    rotate 60 
    create 644 daemon daemon
    sharedscripts 
    postrotate 
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript 
}

保存します。

・確認します

logrotate -dv /etc/logrotate.d/httpd

reading config file /etc/logrotate.d/httpd                                                                          
Allocating hash table for state file, size 15360 B                                                                  
                                                                                                                    
Handling 1 logs                                                                                                     
                                                                                                                    
rotating pattern: /usr/local/apache2/logs/*log  after 1 days (60 rotations)                                         
empty log files are rotated, old logs are removed                                                                   
considering log /usr/local/apache2/logs/access_log                                                                  
  log does not need rotating (log has been already rotated)considering log /usr/local/apache2/logs/error_log        
  log does not need rotating (log has been already rotated)not running postrotate script, since no logs were rotated

なんとか最後までできたようです。

Apache httpd 2.4.27 + mod_http2 インストールメモ | あぱーブログ さんのブログが無かったら確実にできなかったですね、ありがたやー、ありがたや。

久々に、Docker触ったら、かなり忘れてました、オーマイガー!定期的に触れるようにしないとですね。