TOC
ローカルでHTTPサーバーを建てる
ローカルやLAN内でHTTPサーバーを建てて動作確認をしたい時の簡単な手順をまとめました。
まずは追加インストールする必要なく使える可能性の高いPython(3)、Javaで開発をする人ならインストールしている可能性の高いJava1、組み込みで使われることの多いBusyBoxのHTTPサーバー機能の3つとNGINXを一番シンプルにHTTPサーバーとして使う場合のDockerでの使い方についてまとめました。
動作確認はRaspberry Pi 4上のUbuntu Server 22.04 LTSで行っています。
試しにJava SEのJavadocを展開してブラウザから見れるようにする
具体的にローカルやLAN内でHTTPサーバーで何を見るかというと、JavaのJavadocなんかはクラス名の検索では古いバージョンがたくさん引っかかって時間がかかったりする2ものなので、今回はこれをブラウザから見れることを確認します。
$ mkdir ~/javadoc19
$ cd ~/javadoc19
$ wget http://download.oracle.com/docs/cds/javase/jp/19.zip
$ unzip 19.zip
Python
http.server — HTTP servers — Python 3.11.3 documentation
今やどんなLinux環境でもデフォルトでインストールされていると言っても過言ではないPythonは、http.server
モジュールを指定して実行することでHTTPサーバーを構築できます。
引数で色々指定可能です。以下で指定しない場合の引数はbindするポート番号を記載します(デフォルト8000)
-b/--bind IPアドレス
bindするIPアドレスを指定します。指定しない場合はすべてのインタフェースをbindします(3.4で追加、3.8でIPv6アドレスにも対応)-d/--directory ルートディレクトリ
指定したディレクトリをHTTPサーバーのrootにします(3.7で追加)-p/--protocol HTTP/1.1
使用するHTTPのバージョンを指定します。デフォルトではHTTP/1.0になっています(3.11で追加)$ python3 -m http.server 8000 -b 0 -d ~/javadoc19/ Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
F72954_01→APIドキュメントと進むといつものJavadocが表示されます。
index.htmlがない場合はディレクトリリストが表示されます。停止する場合はCtrl+cで止まります。
Java(Java18以降)
JavaにはJava6で導入されたcom.sun.net.httpserver
パッケージがありましたが、Java18でコマンド一つで簡易HTTPサーバーを実行できるようにJEP408が追加されました。jwebserver
コマンドとしても実行可能です。3
Ubuntu 22.04でのインストール
Ubuntu 22.04ではJava19まで標準のパッケージがあります(universeに入っています)
$ apt-cache policy openjdk-19-jdk
openjdk-19-jdk:
インストールされているバージョン: (なし)
候補: 19.0.2+7-0ubuntu3~22.04
バージョンテーブル:
19.0.2+7-0ubuntu3~22.04 500
500 http://ports.ubuntu.com/ubuntu-ports jammy-updates/universe arm64 Packages
500 http://ports.ubuntu.com/ubuntu-ports jammy-security/universe arm64 Packages
Ubuntuのパッケージでは現在もJDKとJREが分けて管理されているので、開発にJava19を使う予定がない場合はJREをインストールするとダウンロードサイズとストレージを節約できます。
# apt-get install openjdk-19-jre
既に他のJavaバージョンをインストールしている場合は実行されるjavaコマンドのパスを確認しましょう。
$ update-alternatives --list java
/usr/lib/jvm/java-11-openjdk-arm64/bin/java
/usr/lib/jvm/java-17-openjdk-arm64/bin/java
/usr/lib/jvm/java-18-openjdk-arm64/bin/java
/usr/lib/jvm/java-19-openjdk-arm64/bin/java
/usr/lib/jvm/java-8-openjdk-arm64/jre/bin/java
$ update-alternatives --config java
alternative java (/usr/bin/java を提供) には 5 個の選択肢があります。
選択肢 パス 優先度 状態
------------------------------------------------------------
* 0 /usr/lib/jvm/java-19-openjdk-arm64/bin/java 1911 自動モード
1 /usr/lib/jvm/java-11-openjdk-arm64/bin/java 1111 手動モード
2 /usr/lib/jvm/java-17-openjdk-arm64/bin/java 1711 手動モード
3 /usr/lib/jvm/java-18-openjdk-arm64/bin/java 1811 手動モード
4 /usr/lib/jvm/java-19-openjdk-arm64/bin/java 1911 手動モード
5 /usr/lib/jvm/java-8-openjdk-arm64/jre/bin/java 1081 手動モード
現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください:
また、LTSであるJava8/11/17を既に別の用途で使っている場合はデフォルト実行はそっちを指すように変更して、Java18以降はフルパスで実行するようにするほうが長期的に見て安全です。
# update-alternatives --config java
alternative java (/usr/bin/java を提供) には 5 個の選択肢があります。
選択肢 パス 優先度 状態
------------------------------------------------------------
* 0 /usr/lib/jvm/java-19-openjdk-arm64/bin/java 1911 自動モード
1 /usr/lib/jvm/java-11-openjdk-arm64/bin/java 1111 手動モード
2 /usr/lib/jvm/java-17-openjdk-arm64/bin/java 1711 手動モード
3 /usr/lib/jvm/java-18-openjdk-arm64/bin/java 1811 手動モード
4 /usr/lib/jvm/java-19-openjdk-arm64/bin/java 1911 手動モード
5 /usr/lib/jvm/java-8-openjdk-arm64/jre/bin/java 1081 手動モード
現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 2
update-alternatives: /usr/bin/java (java) を提供するためにマニュアルモードで /usr/lib/jvm/java-17-openjdk-arm64/bin/java を使います
JavaのHTTPサーバー機能/jwebserverコマンド引数は以下の通り。
-b/--bind-address IPアドレス
bindするIPアドレスを指定します。デフォルトは127.0.0.1または::1。全てのインタフェースを指定する場合は-b 0.0.0.0
または-b ::
-d/--directory ルートディレクトリ
指定したディレクトリをHTTPサーバのrootにします。デフォルトはカレントディレクトリ-o/--output ログレベル
出力フォーマットを指定します。ログレベルはnone/info/verbose
で、デフォルトはinfo
-p/--port ポート番号
listenするポート番号を指定します。デフォルトは8000$ /usr/lib/jvm/java-19-openjdk-arm64/bin/java -m jdk.httpserver -b 0 -d ~/javadoc19/ /home/hogehoge/javadoc19およびサブディレクトリを0.0.0.0 (すべてのインタフェース)ポート8000で使用します URL http://192.168.1.210:8000/
F72954_01→APIドキュメントと進むといつものJavadocが表示されます。
index.htmlがない場合はディレクトリリストが表示されます。停止する場合はCtrl+cで止まります。
BusyBox
BusyBox - The Swiss Army Knife of Embedded Linux
組み込み向けで使われることの多いBusyBoxはHTTPサーバーとしても機能します。Python/Javaと比べてサーバーサイドでのプログラム実行も可能ですが、ここではシンプルなHTTPサーバーとしてbusyboxを実行します。
指定できる引数は相当多いのですが、今回は簡易HTTPサーバーで使うものだけ取り上げます。
-f
daemonとして起動しない(おそらくフォアグラウンドの略)-p (IPアドレス:)ポート番号
bindする(IPアドレスと)ポート番号を指定します。デフォルトは80-h ルートディレクトリ
指定したディレクトリをHTTPサーバのrootにします。デフォルトはカレントディレクトリ
Ubuntu 22.04でのインストール
# apt-get install busybox
$ busybox httpd -f -p 8000 -h ~/javadoc19/
busyboxはindex.htmlがなかった場合にディレクトリリストを表示してくれる機能がないので、html(今回の場合 http://192.168.1.210:8000/F72954_01/docs/api/index.html )を直接ブラウザから叩く必要があります。
停止する場合はCtrl+cで止まります。
NGINX(Dockerで)
上で記載したPython/Java/BusyBoxはコマンドを実行してHTTPサーバを動作させるというものでしたが、OSを再起動しても使い続けたい場合など、継続性の手間を考慮すると普通のHTTPサーバをdockerで動かすというのも一つの方法になると思います。
今回はNGINXを(よくあるリバースプロキシではなく)シンプルなHTTPサーバとして実行し、ルートディレクトリは任意のディレクトリ、起動・終了をdocker-composeで制御する場合を考えてみます。
一般ユーザーで実行する場合はRootless Dockerで
一般ユーザーでdockerを使う場合、dockerグループを作って作業ユーザーをdockerグループに追加するという手順も取れますが、今回はRootless Dockerを使えるようにして作業します。手順は以下の通り。
Dockerをrootlessに変更してrootユーザーの呪縛から開放される
標準的な設定からの変更箇所
NGINXは色々な用途に使うことができるため設定項目も多いのですが、今回は単純によくある設定から少ない変更で済ませるため、以下の3つの要素でdocker-composeから制御するようにします。
- docker-compose.yml
- default.conf (docker-compose.ymlと同じディレクトリに配置)
- ルートディレクトリ(Rootless Dockerの実行ユーザーで読み取れるようにする)
docker-compose.yml
version: "3"
services:
nginx:
image: nginx:stable
container_name: nginx00
ports:
- "8080:80"
restart: unless-stopped
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
- /mnt/usbhdd1/var/docker-nginx:/usr/share/nginx/html
services-nginxの下の要素について以下のようにしています。
- image→nginx:stable dockerhubを見ると、現在1.23.4がmainlineとして、1.24がstableとして公開されているので、1.24を選択(Debian Bullseye)
- ports→8080:80 実ポート番号として公開するのは8080
- volumes(1つ目)→./default.conf:/etc/nginx/conf.d/default.conf docker-compose.ymlと同じディレクトリにdefault.confを置いて、コンテナから見た/etc/nginx/conf.d/default.confとして読み込む
- volumes(2つ目)→/mnt/usbhdd1/var/docker-nginx:/usr/share/nginx/html HTTPサーバーのドキュメントルートとして、実ファイルシステムの /mnt/usbhdd1/var/docker-nginx ディレクトリを読み込む
default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
デフォルトのdefault.confからの変更は以下の通りです。
- location / にautoindex on他を設定(index.htmlがない場合にディレクトリリストを表示する)
確認事項は以下の通りです。
- listenに指定するポート番号が80になっている(コンテナ内のポート番号をdocker-compose.ymlで8080に対応させるポート番号になっている)
- location /のrootが /usr/share/nginx/html になっている(docker-compose.ymlのvolumesとしてドキュメントルートに対応させるディレクトリになっている)
ドキュメントルートにするディレクトリはdocker-compose upの前にディレクトリを作る
ドキュメントルートのディレクトリは先にディレクトリを作らないとdockerにその名前でファイル(ディレクトリではない)を作られてしまうので、予めディレクトリを作っておきます。
また、このディレクトリ配下のファイルはRootless Dockerの実行ユーザー(私の場合は166535)が読み込めるパーミッションでないと表示できるようにならないので、一般ファイルは644、ディレクトリは755にするのが無難です。
コンテナの実行
初回はコンテナをdockerhubからダウンロードするので、時間がかかるため、-d
を付けずに起動するのがいいでしょう。
$ docker-compose up
Creating network "docker-nginx_default" with the default driver
Creating nginx00 ... done
Attaching to nginx00
nginx00 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx00 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx00 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx00 | 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
nginx00 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx00 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx00 | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: using the "epoll" event method
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: nginx/1.22.1
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: OS: Linux 5.15.0-1026-raspi
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: start worker processes
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: start worker process 23
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: start worker process 24
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: start worker process 25
nginx00 | 2023/04/09 02:22:27 [notice] 1#1: start worker process 26
こんな感じの表示になったら起動しているので、試しにブラウザからアクセスするとログが表示されます。
nginx00 | 172.25.0.1 - - [09/Apr/2023:02:25:25 +0000] "GET / HTTP/1.1" 200 457 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" "-"
コンテナ動作を確認できたらCtrl+cで止めます。
^CGracefully stopping... (press Ctrl+C again to force)
Stopping nginx00 ... done
動作確認ができたら2回目以降は非同期実行でいいでしょう。
$ docker-compose up -d
Starting nginx00 ... done
docker-compose.ymlにrestart: unless-stopped
を記載しているので、OSを再起動しても自動的にコンテナを起動します。
スポンサーリンク
comments powered by Disqus