Raspberry Pi Zero WにNginxをインストールしてCGIを動かす

Raspberry Pi Zero WにnginxをインストールしてCGIが動く環境を構築してみました。

はじめに

ラズパイに作成したプログラムをWebブラウザから起動できるとPCやスマホのブラウザから実行することができ便利です。

CGIはファイルを1つ配置するだけでサーバーサイドで動く簡易的なプログラムを作成でき、Webブラウザから起動できるツールを気軽に作成できるようになります。

CGIとは

CGI「Common Gateway Interface」はウェブサーバ上でプログラムを動作させる仕組みです。

ウェブサーバプログラムから他のプログラムを実行して処理結果をクライアントに送信するインターフェースの取り決めです。

CGIは毎回ウェブサーバプログラムから実行するプログラムのプロセスを起動するため負荷が大きくなります。

この負荷が大きくなる問題を改善する目的で開発された仕様にFastCGIがあり、nginxで動く実装のfcgiwrapを用いてCGIが動く環境を構築することにしました。

環境構築

動作環境はラズパイは Raspberry Pi Zero W、OSはRaspbianです。

pi@raspberrypi:~ $ cat /etc/os-release

PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

nginxのインストール

まずnginxをインストールします。拡張モジュールが同梱されているnginx-extrasを使用することにしました。

sudo apt install -y nginx-extras

インストールが完了したらWelcomeページが表示されるかブラウザでアクセスしてみます。

Welcomeページの確認

fcgiwrapのインストール

続いてfcgiwrapをインストールします。

sudo apt install -y fcgiwrap

fcgiwrapに付属しているサンプルの設定ファイルを「/etc/nginx/」以下にコピーします。

sudo cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf

「/etc/nginx/sites-enabled/default」にfcgiwrapの設定ファイルを読込む設定を追加します。

念のため設定ファイルをバックアップしておきます。

cp -p /etc/nginx/sites-enabled/default ./

viエディターで設定ファイルを開きます。(お好みのテキストエディタを使用してください)

sudo vi /etc/nginx/sites-enabled/default

serverブロックの中に以下の内容を追加します。

include /etc/nginx/fcgiwrap.conf;

編集した差分は以下です。

/etc/nginx/sites-enabled/defaultを編集した差分

設定ファイルに問題がないか確認します。

sudo nginx -t

「test is successful」 と表示されたので大丈夫です。

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

nginxのサービスをリロードします。

sudo service nginx reload

ここで念のためラズパイの再起動も行いました。

CGIプログラムの作成

それではCGIプログラムを作成します。
CGIプログラムはどこに配置すればよいでしょうか?

コピーしたfcgiwrapの設定ファイルの内容を確認してみます。

cat /etc/nginx/conf.d/fcgiwrap.conf

ファイルの行数が多くないのでファイルの内容を以下に記載しておきます。

# Include this file on your nginx.conf to support debian cgi-bin scripts using
# fcgiwrap
location /cgi-bin/ {
  # Disable gzip (it makes scripts feel slower since they have to complete
  # before getting gzipped)
  gzip off;

  # Set the root to /usr/lib (inside this location this means that we are
  # giving access to the files under /usr/lib/cgi-bin)
  root  /usr/lib;

  # Fastcgi socket
  fastcgi_pass  unix:/var/run/fcgiwrap.socket;

  # Fastcgi parameters, include the standard ones
  include /etc/nginx/fastcgi_params;

  # Adjust non standard parameters (SCRIPT_FILENAME)
  fastcgi_param SCRIPT_FILENAME  /usr/lib$fastcgi_script_name;
}

locationが「/cgi-bin/」、rootは「/usr/lib」となっていました。

このサンプルの設定では「/usr/lib/cgi-bin/」以下に配置したファイルがCGIとして実行されることがわかります。

フォルダを作成します。

sudo mkdir /usr/lib/cgi-bin

CGIプログラムを作成します。

sudo vi /usr/lib/cgi-bin/hello

作成したCGIプログラムの内容は以下です。「df -h」コマンドの結果と「vmstate」コマンドの結果をHTMLで出力するシェルスクリプトです。

#!/bin/bash

echo 'Content-Type: text/html; chatset=utf-8'
echo
echo '<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>Hello CGI!</title>
  </head>
  <body>
    <h1>Hello CGI!</h1>
    <h2>DF</h2>
    <pre>'"$(df -h)"'</pre>
    <h2>VMSTAT</h2>
    <pre>'"$(vmstat)"'</pre>
  </body>
</html>
'

nginxサービスの実行ユーザーを確認します。

cat /etc/nginx/nginx.conf | grep user

実行ユーザーはwww-dataでした。作成したCGIプログラムの所有者の変更を行います。

sudo chown www-data:www-data /usr/lib/cgi-bin/hello

CGIプログラムの所有者に実行権限を追加します。

sudo chmod u+x /usr/lib/cgi-bin/hello

作成したCGIプログラムにブラウザでアクセスしてみます。パスは「/cgi-bin/hello」です。

ブラウザでCGIプログラムを表示

無事に表示されました。

まとめ

Raspberry Pi Zero Wにnginxとfcgiwrapをパッケージマネージャーで入れるだけでCGIを動かす環境を簡単に構築することができました。

PCやスマホのブラウザとラズパイをつなぐインターフェースとして活用できそうです。

  • Raspberry Pi is a trademark of Raspberry Pi Ltd. — Raspberry Pi