Docker 入門
さまざまな Web サーバを Docker Compose で構築する
nginx のリバースプロキシ,および複数の Apache コンテナの組合せで /site-a/ と /site-b/ を運用する
前のページでは1個の apache コンテナ上で複数のバーチャルホストを構築しました.このため,例えば site-a のバーチャルホストにおいてトラブルが起こったり設定を変更するなどしてコンテナが停止したり再起動している間は,site-b やトップページも Web サービスが停止することに注意してください.ここでは apache のバーチャルホストではなく,複数の apache コンテナを起動して全体としては同様のサービスを設定します.これにより,たとえ site-a のコンテナ停止や再起動中であっても site-b やトップページはサービス提供を継続することができるようになります.なお,このページのサンプルコードは GitHub の web05NginxApache フォルダで公開しています.
まず,例によって任意の新規ディレクトリを作成し,その中に次の構成でディレクトリとファイルを設置します.なお,ログファイルは実行時に自動的に生成されるのでディレクトリと .gitignore だけを作成します.
% tree -a -F ⏎
./
├── apache/
│ └── conf/
│ ├── httpd7000.conf
│ ├── httpd8000.conf
│ └── httpd9000.conf
├── docker-compose.yml
├── nginx/
│ └── conf.d/
│ └── default.conf
├── Readme.md
└── web/
├── html7000/
│ └── index.html
├── html8000/
│ └── index.html
├── html9000/
│ └── index.html
└── logs/
├── apache7000/
│ ├── .gitignore
│ ├── access_log
│ └── error_log
├── apache8000/
│ ├── .gitignore
│ ├── access_log
│ └── error_log
├── apache9000/
│ ├── .gitignore
│ ├── access_log
│ └── error_log
└── nginx/
├── .gitignore
├── access.log
└── error.log
14 directories, 21 files
全体の設計図である docker-compose.yml は次の内容にします.ここで apache コンテナを起動するサービスが3個定義されていることに注意してください.また,apache/conf/ ディレクトリに httpd7000.conf, httpd8000.conf, httpd9000.conf という3種類の設定ファイルがありますが,これらをコンテナの httpd.conf という名称でボリュームとして設定していることにも注意してください.
docker-compose.yml
services:
apache5-7000:
image: httpd:latest
container_name: apache5-7000
expose:
- "7000:7000"
volumes:
- ./apache/conf/httpd7000.conf:/usr/local/apache2/conf/httpd.conf
- ./web/html7000:/usr/local/apache2/htdocs7000/
- ./web/logs/apache7000:/usr/local/apache2/logs/
apache5-8000:
image: httpd:latest
container_name: apache5-8000
expose:
- "8000:8000"
volumes:
- ./apache/conf/httpd8000.conf:/usr/local/apache2/conf/httpd.conf
- ./web/html8000:/usr/local/apache2/htdocs8000/
- ./web/logs/apache8000:/usr/local/apache2/logs/
apache5-9000:
image: httpd:latest
container_name: apache5-9000
expose:
- "9000:9000"
volumes:
- ./apache/conf/httpd9000.conf:/usr/local/apache2/conf/httpd.conf
- ./web/html9000:/usr/local/apache2/htdocs9000/
- ./web/logs/apache9000:/usr/local/apache2/logs/
nginx:
image: nginx:latest
container_name: nginx5
ports:
- "80:80"
depends_on:
- apache5-7000
- apache5-8000
- apache5-9000
volumes:
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
- ./web/logs/nginx:/var/log/nginx
次は nginx のリバースプロキシを設定します.具体的には,http://localhost/site-a/ 以下のリクエストは 8000 番ポートを通じて apache5-8000 サービスへ転送し,http://localhost/site-b/ 以下のリクエストは 9000 番ポートを通じて apache5-9000 サービスへ転送します.さらに,それ以外の URI へのリクエストは 7000 番ポートを通じて apache5-7000 サービスへ転送します.
nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
location /site-a/ {
proxy_pass http://apache5-8000:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /site-b/ {
proxy_pass http://apache5-9000:9000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://apache5-7000:7000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
続いて apache の設定ファイルを3種類準備します.それぞれポート番号に関する部分が異なるのみです.
apache/conf/httpd7000.conf
ServerRoot "/usr/local/apache2"
#Listen 12.34.56.78:80
Listen 7000
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
<IfModule unixd_module>
User www-data
Group www-data
</IfModule>
# 'Main' server configuration
ServerAdmin you@example.com
#ServerName www.example.com:80
<Directory />
AllowOverride none
Require all denied
</Directory>
# DocumentRoot "/usr/local/apache2/htdocs"
<Directory "/usr/local/apache2/htdocs">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
<Files ".ht*">
Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
</IfModule>
<IfModule cgid_module>
#Scriptsock cgisock
</IfModule>
<Directory "/usr/local/apache2/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule headers_module>
RequestHeader unset Proxy early
</IfModule>
<IfModule mime_module>
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule proxy_html_module>
Include conf/extra/proxy-html.conf
</IfModule>
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
<VirtualHost *:7000>
DocumentRoot "/usr/local/apache2/htdocs7000"
<Directory "/usr/local/apache2/htdocs7000">
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
apache/conf/httpd8000.conf
ServerRoot "/usr/local/apache2"
#Listen 12.34.56.78:80
Listen 8000
LoadModule mpm_event_module modules/mod_mpm_event.so
...(中略)...
<VirtualHost *:8000>
DocumentRoot "/usr/local/apache2/htdocs8000"
<Directory "/usr/local/apache2/htdocs8000">
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
apache/conf/httpd9000.conf
ServerRoot "/usr/local/apache2"
#Listen 12.34.56.78:80
Listen 9000
LoadModule mpm_event_module modules/mod_mpm_event.so
...(中略)...
<VirtualHost *:9000>
DocumentRoot "/usr/local/apache2/htdocs9000"
<Directory "/usr/local/apache2/htdocs9000">
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
それぞれのサイトで提供するためのコンテンツを作成します.これらは docker-compose.yml の9行目,19行目,29行目において設置するディレクトリが定義されていることに注意して作成してください.
web/html7000/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apache</title>
</head>
<body>
<h1>Hello Apache</h1>
<p>
Hello Apache
</p>
<p>
このサイトはNginxのリバースプロキシと3個のApacheコンテナで構築しています.
</p>
<h2>リンク</h2>
<ul>
<li><a href="/">トップページ</a>(このページ)</li>
<li><a href="/site-a/">Site-A</a></li>
<li><a href="/site-b/">Site-B</a></li>
</ul>
</body>
</html>
web/html8000/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apache</title>
</head>
<body>
<h1>Hello Apache</h1>
<p>
Hello Apache Site-A
</p>
<p>
このサイトはNginxのリバースプロキシと3個のApacheコンテナで構築しています.
</p>
<h2>リンク</h2>
<ul>
<li><a href="/">トップページ</a></li>
<li><a href="/site-a/">Site-A</a>(このページ)</li>
<li><a href="/site-b/">Site-B</a></li>
</ul>
</body>
</html>
web/html9000/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apache</title>
</head>
<body>
<h1>Hello Apache</h1>
<p>
Hello Apache Site-B
</p>
<p>
このサイトはNginxのリバースプロキシと3個のApacheコンテナで構築しています.
</p>
<h2>リンク</h2>
<ul>
<li><a href="/">トップページ</a></li>
<li><a href="/site-a/">Site-A</a></li>
<li><a href="/site-b/">Site-B</a>(このページ)</li>
</ul>
</body>
</html>
アクセスログファイルが出力されるするそれぞれのディレクトリには .gitignore を設置し,ログファイルが Git のリポジトリに登録されないようにするため *
だけを指定しておきます.
web/logs/*/.gitignore
*
すべての準備ができたらコンテナを起動します.このとき,4個のコンテナ(と1つのネットワーク)が1つのコマンドで起動できていることに注意してください.
% docker compose up -d ⏎
[+] Running 5/5
✔ Network web05nginxapache_default Created 0.0s
✔ Container apache5-8000 Started 0.2s
✔ Container apache5-7000 Started 0.2s
✔ Container apache5-9000 Started 0.2s
✔ Container nginx5 Started 0.2s
%
起動中のコンテナを一覧で確認します.
% docker container ls ⏎
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4ac3c1624a4 nginx:latest "/docker-entrypoint.…" 17 seconds ago Up 16 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp nginx5
e79a140b05d4 httpd:latest "httpd-foreground" 17 seconds ago Up 16 seconds 0/tcp, 80/tcp apache5-9000
d95be1282706 httpd:latest "httpd-foreground" 17 seconds ago Up 16 seconds 0/tcp, 80/tcp apache5-7000
c543e6e05275 httpd:latest "httpd-foreground" 17 seconds ago Up 16 seconds 0/tcp, 80/tcp apache5-8000
%
コンテナの起動が確認できたので Web ブラウザで http://localhost/ や http://localhost/site-a/ および http://localhost/site-b/ に接続します.
コンテナを終了して廃棄します.
% docker compose down ⏎ [+] Running 5/5 ✔ Container nginx5 Removed 0.2s ✔ Container apache5-9000 Removed 1.2s ✔ Container apache5-8000 Removed 1.2s ✔ Container apache5-7000 Removed 1.2s ✔ Network web05nginxapache_default Removed 0.2s % docker container ls -a ⏎ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES %
ここでは nginx のリバースプロキシと3個の apache web サーバで環境を構築しました.次のページでは web サーバについて apache の代わりに nginx で構築する方法を試します.