5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Dockerを使ってPerl製Webアプリケーションを動かしてみる

Posted at

はじめに

perlを使った開発に本格的に取り組むことになりそうだったので理解するためにまずはWebアプリケーションを作ってみる。
今回のゴールとしてはリクエストを受けてレスポンスを正常に返すところまでとする。

Dockerfileの用意

FROM perl:5.18

WORKDIR /srv/sources

RUN cpanm Server::Starter
RUN cpanm HTTP::Router
RUN cpanm Plack                                                                                                                                                                                                                                                                                                           
RUN cpanm Gazelle

本当はcartonを使ってモジュール管理をするのがいいみたいだけども今回はとりあえず一つずつ必要なモジュールをインストールする。
一つのRUNにまとめても良かったが必要になったタイミングでコマンド追加という風にやっていたせいで、都度ビルドを行うと全てのインストールが再度行われて時間がかかりすぎるため、コマンドを分割することにした。

以下、使用するモジュールの用途について。

Server::Starter

プロセスのHot deployに対応するためのモジュール。
詳しい内容についてはこちらの記事で紹介されている。

HTTP::Router

ルーティングを行うためのモジュール。

Plack

PSGIサーバモジュール。
PSGIについてはこちらの記事を読むといいかもしれない。
これでリクエストの処理やレスポンスの構築などを行う。

Gazelle

高速なアプリケーションサーバモジュール。
Gazelleについてはこちらの記事で紹介されているのでこちらを参照するといい。

docker-compose

docker-compose.yml
version: '3'
services:
  app:
    build: ./docker
    ports:
      - 8080:80
    volumes:
      - ./:/srv/sources
    command: ["start_server", "--port", "80", "--", "plackup", "-I", "src/", "-s", "Gazelle", "-E", "development", "app.psgi"]         

アプリケーションのdockerへのマウントはdocker-compose側で行う。(その方が楽だったので)

app.psgi

app.psgi
use strict;
use warnings;
use utf8;

use Plack::Request;
use Plack::Response;
use Data::Dumper;
use HTTP::Router::Declare;
 
use API;                                                                                                                                                                                                                                                                                                                  
 
my $router = router {
  match '/', { method => 'GET' }, to { app => \&API::top }
};

sub dispatch {
  my ($req) = @_;
  my $match = $router->match($req) or return $req->new_response(404)->finalize;
  return $match->params->{ app }($req, $match)->finalize;
}

my $app = sub {
  my $req = Plack::Request->new(shift);
  my $r = eval { dispatch($req) };
  my $errstr = $@ or return $r;

  warn $errstr;

  my $res = $req->new_response(503);
  $res->content_type('text/html');
  $res->body('Error');

  return $res->finalize;
};

エントリーポイントのファイル。
実処理を書くと無駄に長くなるのでそれは別ファイルに分離。

APIモジュール

API.pm
package API;

use strict;
use warnings;
use utf8;

sub top {
  my ($req) = @_;

  my $res = $req->new_response(200);
  $res->content_type('text/html');
  $res->body('Hello');

  return $res;
}

1;      

実処理を記述するファイル。
今回は単純にHelloを返すだけにする。

戸惑った点

開発環境の用意

今まで、PHPやJSぐらいしか書いてこなかったため、エディタや強力なIDEがある環境でやってきたのだけど、いざperlを書こうとした時に良さげなエディタを見つけられずvimで書くことにした。
今までvimも単純にコピペぐらいでしか使っていなかったため、なかなか慣れずに一連のファイルを作るだけでも意外と苦労した。

モジュールのインストール

composerやnpmなんかは配布されているモジュールをインストールするだけなのだが、今回はインストール時にモジュールのテストも行うため、インストールに非常に時間がかかった。
testを無効にできると知ったのは後の祭り。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?