Running Mojolicious in a Docker Container


Mojolicious is a real-time Perl-based web framework that can be used for writing modern web applications. Today in an episode of Stephen Follows Instructions I took it out for a spin. It mostly worked well out of the box, but there were a few quirks that needed some thinking.

I think the main issue with the way it is presented on the website is that the writer assumes you want to install it from scratch. It says "all you need is a one-liner" and then "We recommend the use of a Perlbrew environment." This led me astray last time, and I spent an entire day getting Perlbrew to work. 

Maybe it's a good idea. But I think it's a much better idea these days to start with a Docker image. In my case, I ended up cloning a Mojolicious GitHub repository that set up the Docker image for me, and ran it from there. This mostly worked, but there were some quirks, and a lot of the explanatory text was meaningless (you can watch me struggle with it in my video).

Note that the $UID parameter used in the Tekki/docker-mojolicious documentation fails in my Windows environment, which is why I went straight to the daemon script. This is the dev version, and once dev is done you can run the production version, which is the same except without the word 'morbo' - it took me a long time to figure out how to use the word 'morbo' - the instructions on the Mojolicious home page are just awful, and thank goodness for Gabor and Tekki for some examples that work.

Here's what I did that worked for me (Docker Desktop on Windows 11):

To run Mojolicious with dev environment:

Start up Docker for Desktop

Open VS Code and create a new directory (call it whatever you want)

Open a new terminal in VS Code and run the command:

    git clone https://github.com/Tekki/docker-mojolicious

Then:

    cd docker-mojolicious

Then:

    mkdir script
    cd script


Create a new file called my_app with the following contents:

    #!/usr/bin/env perl
    use Mojolicious::Lite -signatures;

     
    get '/' => sub ($c) {
      $c->render(text => 'Hello World!');
    };
     
    app->start;


Save the file

Then:

    cd ..

Then:

    docker container run --rm -v "$(pwd):/usr/src/app" -p 3000:3000 tekki/mojolicious morbo script/my_app

The Docker container should start up and tell you that "Web application available at http://127.0.0.1:3000". To access your server, navigate to that URL in your web browser.

To edit your applications, edit the file called my_app


----

NOTE

When the Mojolicious documentation says you can test Mololicious from the command line, here's what it means:

You need to open the terminal in to the container itself (use 'Open in Terminal' from Docker Desktop or an exec command (eg. docker exec -it 033bfebab155 sh )

Then you may need to preface the command line command with 'perl'
Eg. :

    perl ./my_app get -M PUT -c '{"message":"Hello Mojo!"}' /reverse

(Not sure why it isn't finding perl, might be mojo, might be me, who knows?)

----

NOTE 2

In the Mojolicious Tutorial, in the section 'Plugins', the example needs to have the 'use' command changed to:

        use Mojolicious::Lite -signatures;

(without -signatures the app just hangs).

--------

NOTE 3

In the Mojolicious tutorial, in the section 'Under', test with:

           http://localhost:3000/?name=Bender

(that's how you generate a value for $c->param('name') in the script)

---------

NOTE 4

In the Mojolicious tutorial, in the section 'External Templates', note that Mojolicious caches the external templates, which means that if you change them, you won't see the update version. 

To disable the cache, insert the following under the 'use' line in the my_app file:

        app->renderer->cache->max_keys(0);

See https://stackoverflow.com/questions/41750243/mojolicious-template-cache-is-stale  

---------

NOTE 5

In the section 'File Uploads' the Mojolicious tutorial does not tell us how to access the uploaded file (which really the whole point of uploading the file).

Here's what I did (from https://dev.to/akuks/how-to-upload-image-in-mojolicious-338f )

    my $name = $example->filename;

    # Get the image object

    my $image = $c->req->upload('example');

    # Give it a place to be stored (in 'public' so I can display it on a web page)

    my $imagename = "public/".$name

    # Move the image file to the place to be stored

    $image->move_to($filename);

    # Display the uploaded image in a web page

    $c->render(text => "<img src='$name'>");



 



Comments

Popular Posts