情報工学徹底攻略実験とレポートの私的学習ガイド

レポート課題44・5日目・180分×2T3情報工学4_[学生番号]_[氏名].pdf

4・5日目 Webサーバー

Webサーバーの定番ソフトNginxをコンテナで動かし、自分で書いたHTMLのページをブラウザに届けます。後半では、Webサーバーが残した記録(アクセスログ)を集計し、グラフつきのレポートにします。

この日のゴール

  • Nginxのコンテナが Docker Compose で動き、80番でWebページを返している
  • Ubuntuに置いた /opt/nginx/html/index.html が、Windowsのブラウザで表示される
  • アクセスの記録(アクセスログ)が Ubuntu 側の /opt/nginx/log/access.log に残っている
  • GoAccessでアクセスログを集計したレポートが、ブラウザで見られる

この日に出てくる主な言葉:

DNS(BIND9)の構築は付録2にまとめられていて、この日のページから参照されています。

Webページが表示されるまで

ブラウザにURLを打ち込むと、ブラウザ(クライアント)とWebサーバーの間で、HTTPという約束事に沿ったやり取りが1往復行われます。考察のヒント課題1は、この流れを一般論ではなく、自分の実験の値(IPアドレス、ポート80、パス、返ってきた200)で説明すると具体的になります。名前で開いた場合は、最初に名前をIPアドレスに変換する段階が加わります。

Windowsのブラウザ Nginx(コンテナ) index.html /opt/nginx/html の中 ① リクエスト GET /index.html HTTP/1.1 ② ファイルを読む ③ 中身 (アクセスログに1行記録する) ④ レスポンス:200 OK + HTML ⑤ HTMLを読んで画面に描く
図1Webページが表示されるまでの1往復。ブラウザが「このファイルをください」と頼み(リクエスト)、Webサーバーがファイルを読んで、結果の番号と中身を返す(レスポンス)。

URLの読み方

http://通信の方式(HTTP)
192.168.100.xxx相手のサーバー(IPアドレスか名前)
:80ポート番号。http なら省略すると80
/goaccess-report.htmlサーバーの中のどのファイルか(パス)

パスを / だけにすると、Webサーバーは決まったファイル(Nginxでは index.html)を返します。

結果の番号(ステータスコード)

表1この実験で見かける主なステータスコード
番号意味この実験で出る場面
200 OK成功ページが正しく表示されたとき
403 Forbidden見せられないindex.html を置く前に / を開いたとき(手順2)考察のヒント403 や 404 が出たことも立派な結果です。「どの段階で、なぜその番号が返ったか」を説明できれば、Webサーバーの仕組みを理解していることを示せます。
404 Not Foundそのファイルはないファイル名の打ち間違い(大文字・小文字も区別される)
502 Bad Gateway取り次ぎ先が応えない6・7日目、Open WebUIがまだ起動していないとき

compose.yaml を読む

この日のcompose.yamlには、Nginx(Webサーバー)と GoAccess(ログの集計係)の2つのサービスが書かれています。

ファイルの中身/opt/nginx/compose.yamlyamlエディタで書く内容(ターミナルに打ち込まない)
services:
  nginx:
    image: nginx:stable
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /opt/nginx/html:/usr/share/nginx/html:ro
      - /opt/nginx/log:/var/log/nginx
    restart: unless-stopped
  goaccess:
    image: allinurl/goaccess
    container_name: goaccess-report
    profiles: ["tools"]
    volumes:
      - /opt/nginx/log:/srv/log:ro
      - /opt/nginx/html:/srv/report
    command:
      - --log-format=COMBINED
      - -f
      - /srv/log/access.log
      - -o
      - /srv/report/goaccess-report.html
表24日目のcompose.yamlの要点
行意味
image: nginx:stableNginxの安定版のイメージを使う
container_name: nginx-proxyコンテナの名前。6日目に「proxy(取り次ぎ役)」として使うので、この名前になっている
ports: - "80:80"Ubuntuの80番を、コンテナの80番につなぐ
volumes:Ubuntuのディレクトリを、コンテナの中のディレクトリとして見せる(バインドマウント。下の図)
:roread only(読み取り専用)。コンテナの中からは書き換えられない
profiles: ["tools"]普段の up では起動しない道具として登録する(プロファイル)。使うときだけ docker compose run で呼ぶ
command:GoAccessに渡す指示。「COMBINED形式のログ /srv/log/access.log を読み、結果を /srv/report/goaccess-report.html に書け」

ホストのディレクトリをコンテナに見せる

Ubuntu(ホスト) コンテナ nginx-proxy /opt/nginx/html あなたが index.html を置く /usr/share/nginx/html Nginxが配信するファイルの置き場 /opt/nginx/log コンテナを消してもログが残る /var/log/nginx Nginxがログを書き込む場所 読むだけ 書き込む
図2バインドマウントの対応。コンテナの中のディレクトリは、実際にはUbuntuのディレクトリそのもの。HTMLはUbuntu側で書き換えるだけで反映され、ログはコンテナを作り直しても残る。

ホストのディレクトリを重ねて見せると、コンテナのイメージに最初から入っていた同じ場所の中身は見えなくなります。これが、次の手順2で最初に「403」が出る理由です。考察のヒントHTMLをUbuntu側に置いたので、ページを書き換えてもコンテナを作り直す必要がなく、コンテナを消してもページとログは残ります。「プログラム(コンテナ)」と「データ(HTML・ログ)」を分けることの利点が、課題2の軸になります。

手順の解説

スクリーンショット(エビデンス)を撮るところ。マウスを乗せると撮るタイミングが表示され、押すとページ下のエビデンス一覧の該当項目へ移動します。考察を書くときに知っておきたいこと。マウスを乗せる(スマホでは押す)とヒントが表示されます。

2.1 第1段階:Nginxだけを動かす

手順 1Windows 11 ターミナル(SSH接続)

ディレクトリとcompose.yamlを作る

Windows 11 ターミナル(SSH接続)bash
sudo mkdir -p /opt/nginx/html
sudo mkdir -p /opt/nginx/log
sudo nano /opt/nginx/compose.yaml

nanoが開いたら、上の compose.yaml の内容を貼り付けて保存します。

手順 2Windows 11 ターミナル(SSH接続)

Nginxを起動して最初の確認をする

Windows 11 ターミナル(SSH接続)bash
cd /opt/nginx
sudo docker compose config
sudo docker compose up -d
sudo docker compose ps

3日目と同じ流れです。ps で nginx-proxy が Up になり、PORTS に 0.0.0.0:80->80/tcp と出ていれば起動しています。エビデンス2の撮影ポイント撮影ポイント エビデンス2手順2の cd /opt/nginx のあとで sudo docker compose ps を実行した直後。nginx-proxy の STATUS が Up、PORTS が 0.0.0.0:80->80/tcp になっていることが分かるように撮る。エビデンス一覧の項目へ移動 ↓goaccess はプロファイル付きなので、ここでは起動しません。

Windows 11 ターミナル(SSH接続)bash
curl http://localhost

ここで「403 Forbidden」が出るのは正常

この時点の /opt/nginx/html は空っぽです。それがコンテナの配信場所に重ねて見せられているので、Nginxは返すべき index.html を見つけられず、403 Forbidden のページを返します。次の手順3でHTMLを置けば解決します。考察のヒント予想と違う結果が出たときに、その理由を仕組みから説明できると、考察の評価が上がります。この403は「空のディレクトリを重ねたことで、イメージに入っていたページが見えなくなった」ことで説明できます。

3日目に見たとおり、Dockerが公開した80番は、ufwで許可していなくても外から届きます(3日目の解説)。

手順 3Windows 11 ターミナル(SSH接続)

HTMLのページを書く

Windows 11 ターミナル(SSH接続)bash
sudo nano /opt/nginx/html/index.html
ファイルの中身/opt/nginx/html/index.htmlhtmlエディタで書く内容(ターミナルに打ち込まない)
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>T3 Lab Web Server</title>
</head>
<body>
  <h1>T3 Lab Web Server</h1>
  <p>Nginx on Docker is running.</p>
</body>
</html>

HTMLは、文章を <タグ> で囲んで、「ここは見出し」「ここは段落」と意味を付けていく言語です。

表3index.html の各部分の意味
部分意味
<!doctype html>「これは今のHTMLの文書です」という宣言
<html lang="ja">文書の始まり。主な言語は日本語
<head> 〜 </head>画面には出ない、文書についての情報
<meta charset="utf-8">文字の符号化方式。日本語を書くなら必須で、ないと文字化けする
<title>ブラウザのタブに出る題名
<body> 〜 </body>画面に表示される本体
<h1>いちばん大きな見出し
<p>段落

中身は自由に変えてかまいません。保存した瞬間から、Nginxはこのファイルを返すようになります。コンテナを作り直す必要がないのは、バインドマウントでUbuntuのファイルをそのまま見せているからです(課題2の材料)。

見出しや表、色づかいを整えたページにしたいときは、サイトを制作で部品を組み合わせて index.html を作り、ここに置き換えられます(必須ではありません)。

手順 4Webブラウザ

ブラウザで表示する

WindowsのブラウザでURL欄に http://192.168.100.xxx/ を入れ、書いたページが表示されることを確かめます。エビデンス1の撮影ポイント撮影ポイント エビデンス1手順4で、ブラウザに手順3で書いたページが表示された時点。URL欄の http://192.168.100.xxx/ も写るように撮る。サーバーの中で curl http://localhost を実行し、HTMLが返ってきた画面でもよい。エビデンス一覧の項目へ移動 ↓サーバーの中からは curl http://localhost でもHTMLの中身が返ってきます。

http://www.t3.metro-cit.internal で開けないとき

名前で開くには、Windows側がその名前をあなたのサーバーのIPアドレスに結びつけられる必要があります。その方法が、Windowsのhostsファイル(1日目)か、DNS(付録2)です。どちらも準備していなければ名前では開けないので、IPアドレスで確かめてください。指導書も「または」と両方を挙げています。

2.2 第2段階:アクセスログを集計する

手順4までにブラウザでページを開くたびに、Nginxはその記録をアクセスログに1行ずつ書き足しています。第2段階では、GoAccessというツールでそれを集計し、グラフつきのHTMLのレポートにします。集計する前に、ブラウザで何度かページを再読み込みしたり、わざと存在しないページ(http://192.168.100.xxx/nothing.html など)を開いたりして、記録を増やしておくと、レポートが見やすくなります。

アクセスログの1行を読む

画面の表示例/opt/nginx/log/access.log の1行の例打ち込むものではなく、表示の例
192.168.100.50 - - [29/Sep/2026:10:15:32 +0000] "GET / HTTP/1.1" 200 180 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) … Chrome/… Safari/537.36"
192.168.100.50アクセスしてきた相手のIPアドレス
- -利用者の識別(今回は使われていない)
[29/Sep/2026:10:15:32 +0000]日時(+0000 はUTC)
"GET / HTTP/1.1"要求の内容
200結果の番号(ステータスコード)
180返したデータの大きさ(バイト)
"-"どのページから来たか(直接なら -)
"Mozilla/5.0 …"ブラウザの種類(User-Agent)

この並び方が「COMBINED(コンバインド)形式」で、GoAccessに --log-format=COMBINED と伝えているのはこのためです。考察のヒントわざと存在しないページを開いて404を記録しておくと、課題3で「異常がレポートのどこにどう現れるか」を、自分のデータで具体的に示せます。

手順 5Windows 11 ターミナル(SSH接続)

GoAccessでレポートを作る

Windows 11 ターミナル(SSH接続)bash
cd /opt/nginx
sudo docker compose run --rm goaccess
docker compose runこのサービスを1回だけ動かす
--rm終わったらコンテナを消す
goaccesscompose.yaml に書いたサービスの名前

GoAccessのコンテナは、ログを読み(/opt/nginx/log を読み取り専用で)、レポートを書き出し(/opt/nginx/html に)、終わると消えます。書き出し先がNginxの配信場所と同じディレクトリなので、できたレポートはすぐにブラウザで見られます。ログが空だとレポートも空っぽになるので、先にアクセスを増やしておきます。エビデンス4の撮影ポイント撮影ポイント エビデンス4手順5でGoAccessを動かす前(後でもよい)に、sudo ls -l /opt/nginx/log/access.log を実行した直後。ファイルがUbuntu側にあり、大きさが0でない(記録がたまっている)ことが分かるように撮る。エビデンス一覧の項目へ移動 ↓

レポートは実行した時点の集計です。新しいアクセスを反映させたいときは、もう一度このコマンドを実行します。

手順 6Webブラウザ

レポートを見る

ブラウザで http://192.168.100.xxx/goaccess-report.html を開きます。エビデンス5の撮影ポイント撮影ポイント エビデンス5手順6で、ブラウザにGoAccessのレポートが表示された時点。URL欄と、上部の集計(Total Requests、Unique Visitors など)が写るように撮る。エビデンス一覧の項目へ移動 ↓英語の表示ですが、主な欄は次のとおりです。

Unique visitors per day
日ごとの訪問者数
Requested Files
よく要求されたページ
Not Found URLs (404s)
存在しないページへの要求。打ち間違いや、弱点を探す自動のアクセスが現れる
Visitor Hostnames and IPs
アクセス元のIPアドレス
Operating Systems / Browsers
アクセスしてきたOSやブラウザの種類
HTTP Status Codes
結果の番号ごとの件数

課題3(運用監視や障害調査での利点)を考えるときは、「生のログを目で追う場合と比べて、何が一目で分かるようになったか」を具体的に書けるよう、レポートの中で気づいたことをメモしておきましょう。考察のヒント生のログを目で追う場合と比べて、何が一目で分かるようになったかを書きます。404の件数、アクセス元の偏り、時間帯など、自分のレポートで実際に見えたことを例に挙げると説得力が出ます。

docker compose logs にアクセスの記録が出ない理由

エビデンス3では docker compose logs --tail 20 でNginxのログを見ますが、ここに出るのは主に起動時のメッセージ(Configuration complete; ready for start up など)です。Nginxの公式イメージは、本来アクセスログを画面側(docker compose logs で見える側)に出す作りですが、この構成では /var/log/nginx にUbuntuのディレクトリを重ねているため、アクセスログはファイル /opt/nginx/log/access.log に書かれます。アクセスの記録はそちらで確かめます。

シェルスクリプトとAIの活用(目的にあるが手順がない項目)

指導書の目的と手順の差

この日の目的には「AI(Gemini等)を活用したトラブルシューティングを体験し、シェルスクリプトによる自動化を行う」とありますが、具体的な手順は書かれていません。授業で指示があるはずなので、ここでは理解のための予備知識と、練習用の例をまとめます。

シェルスクリプトとは

シェルスクリプトは、打ちたいコマンドを順番に書いておいたファイルです。一度書けば、何度でも同じ順番・同じ内容で実行できます。手作業の打ち間違いがなくなり、手順そのものが記録として残ります。指導書の基礎知識が「手動でのサーバー構築作業はミスを誘発しやすい」と書いているのは、このためです。考察のヒント手作業とスクリプトを比べるときは、打ち間違い、同じ結果の再現、ほかの人への引き継ぎ、作業の記録の4点で比べると、自動化の意義を整理しやすくなります。

次は、この日の確認作業をまとめて行う練習用の例です(指導書の手順ではありません)。

Windows 11 ターミナル(SSH接続)bash
nano ~/check-web.sh
ファイルの中身~/check-web.shbashエディタで書く内容(ターミナルに打ち込まない)
#!/bin/bash
# check-web.sh : Webサーバーの状態をまとめて確認する
set -eu

cd /opt/nginx
echo "== コンテナの状態 =="
sudo docker compose ps

echo "== トップページの応答コード =="
curl -s -o /dev/null -w "%{http_code}\n" http://localhost

echo "== アクセスログの行数 =="
sudo wc -l /opt/nginx/log/access.log
表4スクリプトの各行の意味
行意味
#!/bin/bashこのファイルを bash で実行する、という指定(シバン(#!))。必ず1行目に書く
# …コメント(説明のメモ)
set -eu途中でエラーが起きたらそこで止まる(-e)、書き間違えた変数を使ったら止まる(-u)。失敗に気づかず先へ進むのを防ぐ
echo "…"文字を表示する。見出しの代わり
curl -s -o /dev/null -w "%{http_code}\n" …ページの中身は捨てて(-o /dev/null)、結果の番号だけを表示する。200 なら正常
wc -lファイルの行数を数える。アクセスログ1行=アクセス1回

保存したら、実行してよいファイルという権限を付けてから実行します。

Windows 11 ターミナル(SSH接続)bash
chmod 755 ~/check-web.sh
~/check-web.sh

このように、確認・集計・設定の反映など、毎回同じ手順になる作業は、スクリプトにすると楽で確実になります。レポートにスクリプトを載せるときは、全体を貼るのではなく、工夫した部分を抜き出して本文で説明します(ソースコードの載せ方)。

AIをトラブルシューティングに使うとき

指導書は、AIを「支援役」として使う前提を示しています。質問するときは、環境・やったこと・出たエラーの全文を伝えると、的外れな答えが減ります。そのまま使える相談の型をトラブル対処集にまとめました。AIの提案は必ず自分で意味を確かめてから実行し、レポートで使った場合は付記に書きます。

結果と考察のための確認コマンド

第1段階(Nginxのみ):エビデンス3の撮影ポイント撮影ポイント エビデンス3第1段階の確認で sudo docker compose logs --tail 20 を実行した直後(/opt/nginx で)。起動時のメッセージ(Configuration complete; ready for start up など)が写っていればよい。アクセスの記録はファイル側に書かれるので、ここには出ない。エビデンス一覧の項目へ移動 ↓

Windows 11 ターミナル(SSH接続)bash
curl http://localhost
cd /opt/nginx
sudo docker compose ps
sudo docker compose logs --tail 20

第2段階(Nginx+GoAccess):

Windows 11 ターミナル(SSH接続)bash
cd /opt/nginx
sudo ls -l /opt/nginx/log/access.log
sudo docker compose run --rm goaccess

エビデンス(スクリーンショット5点)

  • ↑ 手順4で撮る
  • ↑ 手順2で撮る
  • ↑ 確認コマンド(第1段階)で撮る
  • ↑ 手順5で撮る
  • ↑ 手順6で撮る

cd /opt/nginx && … の && は、「左のコマンドが成功したら、続けて右のコマンドを実行する」という意味です。

課題を考えるための材料

課題1Webサーバーがブラウザからの要求に応じてコンテンツを返す仕組みを説明せよ。

知っておくとよい事実

  • ブラウザは、URLから相手(名前ならIPアドレスに変換する)とポート(http なら80)を決めて接続し、HTTPのリクエストを送る
  • リクエストには、方法(GET など)、欲しいファイルのパス、ブラウザの情報などが含まれる(3日目の whoami の表示がまさにその中身)
  • Webサーバーは、パスに対応するファイルを探し、結果の番号(ステータスコード)と中身をレスポンスとして返す
  • ブラウザは受け取ったHTMLを解釈して画面を描く

考える観点

  • 図1のような流れを、自分の実験の具体的な値(IPアドレス、パス、200や403)で説明できるか
  • この実験では、Nginxがコンテナの中にいる。Windowsから届いた通信が、どこを通ってNginxにたどり着くか(ポート公開)
  • 手順2の403や、存在しないページの404は、この仕組みのどこで起きたのか
課題2ホスト側で作成したHTMLファイルをDockerコンテナにマウントして配信する方式には、どのような利点があるか説明せよ。

知っておくとよい事実

  • コンテナの中に直接書いたファイルは、コンテナを削除すると一緒に消える
  • バインドマウントでは、コンテナの中の場所が、実際にはホストのディレクトリそのものになる(図2)
  • :ro を付けると、コンテナの側からは書き換えられない
  • 同じディレクトリを、Nginx(読むだけ)とGoAccess(書き込む)という別々のコンテナで共有している

考える観点

  • ページを書き換えるたびにイメージを作り直す方式と比べて、何が楽になり、何が安全になるか
  • Nginxのイメージを新しい版に入れ替えるとき、中身(HTML)はどうなるか
  • 「プログラム(コンテナ)」と「データ(HTML・ログ)」を分けておくことの意味
課題3アクセスログをGoAccessで可視化することで、運用監視や障害調査にどのような利点があるか説明せよ。

知っておくとよい事実

  • アクセスログには、1回のアクセスごとに、相手・日時・要求・結果・大きさ・ブラウザが記録される
  • アクセスが増えると、ログは人が目で追えない量になる
  • GoAccessは、ステータスコードごとの件数、よく見られたページ、404の一覧、アクセス元などを集計して表やグラフにする

考える観点

  • 「障害が起きている」ことに、どの欄を見れば早く気づけるか(404や5xxの急増など)
  • 不審なアクセス(存在しないページを大量に探すなど)は、レポートのどこに現れそうか
  • アクセスの多い時間帯やページが分かると、運用上どんな判断に使えるか
  • 自分のレポートで実際に見えたことを例に挙げると、説得力が増す

あなたの番号を設定

学生番号の下2桁を入れると、このサイトのコマンド例に出てくるIPアドレスやVM IDが、あなた用の値に置き換わります。値はこのブラウザの中だけに保存され、どこにも送信されません。