Blow Up by Black Swan

docker+apache(ubuntu)+pythonでWEBサーバを構築してみる

プログラミング初心者が勉強を進める中で困惑することの一つが「サーバ」という言葉だと思います。プログラミングを勉強する前の私は、コンピュータ機器が入った物理的な箱のことだとばかり思っていましたが、使う場面や人によっては、「ある機能をもったソフトウェア」という意味でも使われます。むしろこちらの方が主流だと思います。私もまだまだプログラミング初心者ですが、最近やっとこの「サーバ」という言葉をすんなり受け止められるようになりました。今回は、その「サーバ」の中でもWEBアプリケーションに必要不可欠な「WEBサーバ」を構築してみたので、それについてまとめました。

1. WEBサーバとは

ブログなどのWEBアプリケーションを利用するとき、Google Chromeなどのブラウザからサーバに対して通信がおこなれます。この通信で利用されるルールのことをHTTPと言いますが、サーバ側でこのHTTPリクエストを処理するのが「WEBサーバ」です。ブラウザから送られるユーザのリクエストに応じて、どういったデータを返すかを決め、ブラウザに返信(レスポンス)する役割を担っています。このときの内部的な処理とインターフェイスは、以前書いた記事の図を見見て頂くとわかりやすいかなと思います。

このWEBサーバで有名なのが、フリーオープンソースソフトウェアのApacheやApacheの問題点を解消するために作られたnginx(エンジンエックス)です。他にもマイクロソフトが出しているIISというWEBサーバも人気のようです。今回は、Apacheを使ってWEBサーバを構築してみました。

2. 構築環境や流れなど

今回の構築環境は以下になります。

#前提環境
PC: Macbook Air
docker: 18.09ver

#構築していくもの
dockerイメージ: ubuntu(18.04bionic)
webサーバ: apache2(aptの標準リポジトリから入手)
python: 3.6.7(ubuntu標準リポジトリから入手)

構築の流れは以下のようになります。

# 静的なHTMLファイルの表示
1. dockerコンテナ構築
   イメージ: ubuntu

2. apacheのインストール
   パッケージ: apache2

3. テスト用HTMLファイルの作成

4. サーバの起動

5. ブラウザからアクセス

# CGIを利用した動的なファイル処理
上記の1,2は同じ
3. 設定ファイルの編集
   設定ファイル: /etc/apache2/conf-available/serve-cgi-bin.conf

4. CGIファイルの作成と実行権限の付与

5. CGIモジュールの有効化
   モジュール: cgid

6. ブラウザからアクセス

3. ubuntuをOSとするときのapacheの設定ファイルの構成等

OSがubuntuの場合、設定ファイルの構成が若干異なるので、ここで簡単にまとめています。

/etc/apache2
 |-- apache2.conf     # Apache2のメインの設定ファイル
 |-- conf-available   # 利用可能な設定ファイルが格納されている. 他のバージョンのconf.cに相当
 |-- conf-enabled     # conf-availableのシンボリックリンクの格納先. ここで示されているファイルが有効になっている設定ファイル
 |-- envvars          # Apache2の環境変数が設定されるファイル
 |-- magic            # MIME typeを決めるためのファイル
 |-- mods-available   # モジュールをロードし、設定するためのファイルが格納されている
 |-- mods-enabled     # mods-availableのシンボリックリンクの格納先. ここで示されているファイルが有効なモジュールの設定ファイル
 |-- ports.conf       # Apache2が利用するポートを設定するファイル
 |-- sites-available  # ヴァーチャルホストを設定するために利用可能な設定ファイルの格納先
 '-- sites-enabled    # sites-availableのシンボリックリンクの格納先. 有効な設定ファイルが示されている

ubuntuの設定ファイルの構成は、CentOSなどよりも少し複雑な構成になっているようです。availableとenabledは、利用可能な設定ファイルの格納先とその中で有効になったファイルを示す先という関係になっています。基本的にはavailbleフォルダ内でファイル作成 -> コマンドを使ってenabledにシンボリックリンクを設定という流れになり、enabledフォルダ内のリンクを直接いじることは基本しません。シンボリックリンクとは、ショートカットに似たもので設定ファイルを読み込むときにenabledを参照 -> そこに記載されたシンボリックリンクを辿ってavailableフォルダ内のファイルを参照という流れのようです。

また、有効化するためのコマンドはa2en(conf, mod, site) 設定ファイル・モジュール名となっており、例えばsites-availableフォルダ内の000-default.confファイルを有効化する場合は、下記のようになります。

$ a2ensite 000-default.conf

このコマンドは下記のようなわかりやすい構成になっています。

  • a2 -> apache2
  • en -> enable(有効化)
  • conf, mod, site -> 対象のファイルがある設定フォルダ

一方で、設定ファイルを無効にする場合は、enをdis(disable:無効化の意味)に変えるだけです。

$ a2dissite 000-default.conf

以上が、ubuntuをOSとするときのApacheの設定ファイルの構造です。しっかり書かれている日本語サイトがあまりなかったので、ここでまとめてみました。

4. 静的ファイルを表示してみる

次は、実際にWEBサーバを構築し、静的なファイルを表示するところまでやってみます。最小限の手順でWEBサーバを構築しているため、サーバネームなどの直接的に関係のない設定は行なっていません。

<1. dockerコンテナ構築>

dockerコンテナを作成します。

※ systemデーモンが関わる場合は、--previlagedオプションをつける必要がある場合もあるようですが、今回は必要ないので設定していません。

$ docker run -it --name apache-test -p 80:80 ubuntu:latest

<2. apacheのインストール>

aptのリポジトリをアップデートした上で、apache2をインストールします。

また、ファイル編集用にvimをインストールしています。

:/# apt update
:/# apt install -y apache2
:/# apt install -y vim

<3. テスト用HTMLファイルの作成>

ブラウザに表示させるためのHTMLファイルを作成します。

:/# touch ~/var/www/html/test.html
:/# vim ~/var/www/htm/test.html

下記が記述内容です。

<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <h1>Test</h1>
    </body>
</html>

このブラウザに返すファイルの置き場(/var/www/html)であるDocumentRootは、/etc/apache2/sites-available/000-default.confに記載されています(初期設定でsites-enabledで有効化されています)。/var/www/html以下にフォルダ構造を作れば、URLもフォル構造にすることができます。(例: /var/www/html/app/01/app01.html -> http://localhost/app/01/app01.htmlでアクセスできる)

<4. サーバの起動>
ApacheでできたWEBサーバを起動します。

サーバネームを設定しないと毎回アラームが出ますが、今回は特に影響がないので放っておきます。

:/# service apache2 start

ちなみにサーバの停止やサーバの稼働状況をみるための便利なコマンドは下記になります。

:/# service apache2 stop    #サーバの停止
:/# service apache2 status  #サーバの状態確認

<5. ブラウザからアクセス>

ブラウザから「http://localhost:80/test.html」にアクセスすると次のような画面が表示されると思います。

実行イメージ

5. pythonスクリプトのCGIを使って、動的なファイル処理をしてみる

次は、CGIを利用して見ます。CGIや静的ファイルについては、わかりやすいサイトが多々あるので調べて見て頂ければと思います。また、WEBサーバとアプリケーションプログラムのインターフェイスの様々な形については、上記でリンクを載せた記事を見て頂ければと思います。dockerの立ち上げから関連パッケージのインストールまでは上記の1,2と同じなので省略しています

<3. 設定ファイルの編集>

CGIを取り扱うためのファイルを編集します。

:/# vim /etc/apache2/conf-available/serve-cgi-bin.conf

元の記載事項に設定を追加して編集しています。

<ifmodule mod_alias.c="">
        <ifmodule mod_cgi.c="">
                Define ENABLE_USR_LIB_CGI_BIN
        </ifmodule>
        <ifmodule mod_cgid.c="">
                Define ENABLE_USR_LIB_CGI_BIN
        </ifmodule>
        <ifdefine enable_usr_lib_cgi_bin="">
                ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/  #追加部分
                <directory "="" usr="" lib="" cgi-bin"="">
                        AllowOverride None
                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                        Require all granted
                        AddHandler cgi-script .cgi  #追加部分
                </directory>
        </ifdefine>
</ifmodule>

ScriptAliasでDocumentRootとは別にCGIファイルの設定場所を指定しています。この指定フォルダ以下のファイルはCGIファイルとして実行されますが、AddHandlerでCGIファイルを、.cgi拡張子を持つものに限定しています。

上記の設定は、「http://localhost/cgi-bin/CGIファイル」にアクセスするとそのCGIファイルが実行された結果がブラウザに返されるということを意味します。

<4. CGIファイルの作成と実行権限の付与>
次は、CGIファイルを作成します。

:/# vim /usr/lib/cgi-lib/test.cgi

CGIファイルの記載内容

#!/usr/bin/python3.6

import datetime

def time_index():
    html = """

CGI Test

The access time: {}
    
    """
    time = datetime.datetime.now()
    return html.format(str(time))

print("Content-Type: text/html;")
print(time_index())

このファイルが実行できるように権限を付与します。

:/# chmod +x /usr/lib/cgi-lib/test.cgi

<5. CGIモジュールの有効化>

最後に設定したCGIモジュールを有効化し、その設定が有効となるようWEBサーバを再起動します。

:/# a2enmod cgid
:/# service apache2 restart

<6. ブラウザからアクセス>

「http://localhost:2000/cgi-bin/test.cgi」にアクセスすることで、実行ファイルの結果がブラウザに表示されると思います。

CGI実行イメージ

6. まとめ

今回は、WEBサーバの構築法についてまとめました。できれば、flaskアプリを利用したものも記載したかったのですが、なぜか実行ができません…泣 おそらくはflaskの設定部分に問題があるのではないかと思うので、おいおい挑戦していきたいと思います。次回はnginxについてまとめようと思います。

読んで頂いた方、どうもありがとうございました。