sironekotoroの日記

Perl で楽をしたい

Mojolicious::Liteで作ったWebアプリをDockerに入れてHerokuで動かす

昔語り

書いてたら止まらなくなってしまったので全部カット

参考・影響を受けた記事&スライド

www.nqou.net

環境

  • macOS 10.12.6
  • heroku CLI(https://devcenter.heroku.com/articles/heroku-cli)

      $ heroku -v
      heroku/7.14.2 darwin-x64 node-v10.9.0
    
  • Docker for Mac(https://store.docker.com/editions/community/docker-ce-desktop-mac)

      $ docker version
      Client:
       Version:           18.06.1-ce
       API version:       1.38
       Go version:        go1.10.3
       Git commit:        e68fc7a
       Built:             Tue Aug 21 17:21:31 2018
       OS/Arch:           darwin/amd64
       Experimental:      false
    
      Server:
       Engine:
        Version:          18.06.1-ce
        API version:      1.38 (minimum version 1.12)
        Go version:       go1.10.3
        Git commit:       e68fc7a
        Built:            Tue Aug 21 17:29:02 2018
        OS/Arch:          linux/amd64
        Experimental:     true
    
  • Perl

      $ perl -v | grep This
      This is perl 5, version 28, subversion 0 (v5.28.0) built for darwin-2level
    
  • cpanm, MojoliciousについてはLocal::Libを利用せず、普通にインストールしてます

    • cpanm

            $ cpanm --version | head -1
            cpanm (App::cpanminus) version 1.7044 (/Users/sironekotoro/.plenv/versions/5.28.0/bin/cpanm)
      
    • mojolicious

            $ mojo version
            CORE
              Perl        (v5.28.0, darwin)
              Mojolicious (7.94, Doughnut)
      
            OPTIONAL
              Cpanel::JSON::XS 4.04+  (4.04)
              EV 4.0+                 (n/a)
              IO::Socket::Socks 0.64+ (n/a)
              IO::Socket::SSL 2.009+  (2.056)
              Net::DNS::Native 0.15+  (n/a)
              Role::Tiny 2.000001+    (2.000006)
      
            This version is up to date, have fun!
      
  • macOSにtreeコマンドなかったんで急遽入れたtree brew install tree

作成手順

Mojolicious::Liteを利用したWebアプリを作る(Perl入学式の範囲)

  1. 今回の作業場所になるフォルダを作成します

    $ mkdir heroku

  2. フォルダの中に移動します

    $ cd heroku/

  3. Dockerfileを作成します(作成だけ)

    $ touch Dockerfile

  4. Webアプリ用のフォルダを作成します

    $ mkdir webapp/

    ここまでのフォルダ構成です。Dockerfileはファイル、webappはフォルダです

      $ tree  
      .
      ├── Dockerfile
      └── webapp
    
      1 directory, 1 file
    
  5. Webアプリ用のフォルダに移動します

    $ cd webapp/

  6. Mojolicious::Liteの雛形を作成します。myapp.plファイルが作成され、実行権限がつきます

    $ mojo generate lite_app

  7. この時点で一度Webアプリを起動して確認しておきます

    $ morbo -l http://*:3000 myapp.pl

  8. ブラウザでhttp://localhost:3000にアクセスし、いつものMojoliciousの画面が出るかどうか確認します

  9. ターミナルをCtrl + cで抜けます

  10. 1つ上の階層に戻ります

    $ cd ../

  11. この時点でのフォルダ構成です

      $ tree
      .
      ├── Dockerfile
      └── webapp
          └── myapp.pl
    
      1 directory, 2 files
    

Dockerイメージの中に、先ほど作ったWebアプリを入れる

  1. Dockerfileを下記の内容で編集します

     # ベースイメージ
     FROM perl:5.28
    
     # Mojolicious::Liteのインストール
     RUN cpanm Mojolicious::Lite
    
     # Dockerイメージ内にウェブアプリケーション用のフォルダを用意して移動
     WORKDIR webapp/
    
     # ホストのwebapp/myapp.plをDockerイメージ内の現在位置(webapp/)にコピー
     # 行末にあるドット . に注意
     COPY webapp/myapp.pl .
    
     # Mojoliciousを起動
     CMD morbo -l http://*:3000 myapp.pl
    
  2. Dockerfileを元にDockerイメージをbuildします
    最後の.を忘れないように

    $ docker build -t mojolicious -f Dockerfile .

  3. Dockerイメージが作成されたか確認します

      $ docker images
      REPOSITORY          TAG                IMAGE ID            CREATED              SIZE
      mojolicious         latest              9241214e107f        About a minute ago   902MB
      perl                5.28                c58a7ea6dfc4        28 hours ago         885MB
    
  4. DockerイメージからDockerコンテナを起動します
    オプションにより、コンテナは実行後破棄されます。また、ホストのポート3000番とDockerコンテナのポート3000番を結びつけ、コンテナにはmojoという名前をつけています

    $ docker run --rm -i -t -p 3000:3000 --name mojo mojolicious

  5. ブラウザでhttp://localhost:3000へアクセスし、いつもの画面が出ることを確認します

    • この時点で実行中のコンテナに入る場合には、別途ターミナルを立ち上げて以下のコマンドを入力します

      $ docker exec -it mojo bash

    • コンテナから抜けるにはexitコマンドで抜けます

  6. ブラウザでの確認が終わったらCtrl + cで終了します

Herokuに先ほど作ったDockerイメージをアップする

  1. Dockerfileの最後の行であるCMD行を修正します

     # Mojoliciousを起動
     # Herokuではポート番号の指定ができない。3000 を $PORT に書き換える
     CMD morbo -l http://*:$PORT myapp.pl
    
  2. Herokuにログインします

      heroku login
      heroku: Enter your login credentials
      Email:heroku-test@sironekotoro.com
      Password: **************************
      Logged in as heroku-test@sironekotoro.com
    
  3. Heroku上でwebアプリ用のスペースを用意します
    ⬢ 以降の文字列がアプリ名、その下の行がアプリ用のURLとgitのリモートリポジトリです

      $ heroku create
      Creating app... done, ⬢ floating-hamlet-68207
      https://floating-hamlet-68207.herokuapp.com/ | https://git.heroku.com/floating-hamlet-68207.git
    
  4. 先ほど用意されたURLにブラウザでアクセスして画面を確認します

    f:id:sironekotoro:20180909145341p:plain

  5. ターミナルに戻り、HerokuのContainer Registryにログインします

      $ heroku container:login
      Login Succeeded
    
  6. HerokuのContainer RegistryにDockerイメージをpushします。-aの後のアプリ名はheroku createで発行されたものを利用します

      $ heroku container:push web -a floating-hamlet-68207
      === Building web (/Users/sironekotoro/Desktop/heroku/Dockerfile)
      (以下略)[f:id:sironekotoro:20180909150557p:plain]
      latest: digest: sha256:08cc85e39e5ab8a6faf0653737d5e9fa658935faab9c30df13f5d3653a327423 size: 2632
      Your image has been successfully pushed. You can now release it with the 'container:release' command.
    
  7. Heroku上でwebアプリをリリースします

      $ heroku container:release web -a floating-hamlet-68207
      Releasing images web to floating-hamlet-68207... done
    
  8. ブラウザでアプリのURL(この例では https://floating-hamlet-68207.herokuapp.com/ )を入力し、アクセスします。なお、初回の表示は少し時間がかかるようです

  9. 表示を確かめてニヤリとします

後片付け

  1. アプリに割り当てられているwebのプロセスを0にします

     $ heroku ps:scale web=0 -a floating-hamlet-68207
     Scaling dynos... done, now running web at 0:Free
    
  2. この時点でWeb上ではエラーが表示されます

    f:id:sironekotoro:20180909152321p:plain

  3. Herokuで作成したアプリを削除します
    本当に消して良いのか再確認を求められるので、アプリ名を入力します

      $ heroku apps:destoroy floating-hamlet-68207
       ▸    WARNING: This will delete ⬢ floating-hamlet-68207 including all add-ons.
       ▸    To proceed, type floating-hamlet-68207 or re-run this command with
       ▸    --confirm floating-hamlet-68207
    
      > floating-hamlet-68207
    
  4. Herokuからログアウトします

      $ heroku logout
      Logging out... done
    
  5. Dockerイメージを削除する場合には、docker imagesを利用してIMAGE IDを確認します
    表示が見切れていると思うので、右側にスクロールしてください

      $ docker images
      REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE
      registry.heroku.com/floating-hamlet-68207/web   latest              282624a4c7c5        11 minutes ago      891MB
      mojolicious                                      latest              60486db357d4        23 minutes ago      891MB
      perl                                             5.28                c58a7ea6dfc4        4 days ago          885MB
    
  6. 確認したIMAGE IDを引数にしてdocker rmiコマンドを実行します
    なお、Perlのイメージファイルは大きいので、今後もPerlを利用したコンテナを作る場合には残しておいた方がよいでしょう

      $ docker rmi 282624a4c7c5 60486db357d4
      Untagged: registry.heroku.com/floating-hamlet-68207/web:latest
      Untagged: registry.heroku.com/floating-hamlet-68207/web@sha256:406a6002c3657824f5e79689c7d4b9083ec50cf64c16c9c5764d451a5567c6dc
      Deleted: sha256:282624a4c7c58dd90c385eb3e1607275bda542db1d278bc3c3c0687846a26ad0
      Untagged: mojolicious:latest
      (中略)
      Deleted: sha256:c42cc493a9c425ca897aaac856b3ae547840b28d34678d19aefcca98b759599e