In this blog series, we will develop a small web application that runs in the IBM Cloud. We will be using an old fashion way called rapid application development and an old framework called Plack, a Perl-based web service.
The purpose is twofold. It demonstrates that traditional style environments can be used to build cloud applications and it also allows us to build a proof of concept in virtually no time.
Let’s get our hands dirty…
Hello world
So here is your basic application that does the usual.
#! /usr/bin/perl use Plack::Builder; use Plack::Response; use strict; sub main { my $env = shift; my $res = Plack::Response->new(200); $res->content_type("text/plain"); $res->body("Hello World"); return $res->finalize; } our $app = builder { mount "/" => \&main; }
This small program sets up a default environment that handles incoming requests. If the incoming request starts with a forward, it redirects to a function called main. The main function creates a response of type 200, which is the web equivalent to “OK, all is well”, the content of type plain/text and the body of the page containing some text, in this case, “Hello World”.
If you have set up your Perl environment correctly, you can simply put this little program in a file called app.psgi and run ‘plackup’ from the command line. The program ‘plackup’ gets installed as a default runner when you install the Plack Perl library. As soon as you start the Plack framework it will tell you where the service is started.
$ plackup HTTP::Server::PSGI: Accepting connections at http://0:5000/
Surfing to your local machine on http://localhost:5000/ should give you a “Hello World” page.
As much as this is not doing a lot of things, it will allow us to build up a Cloud Foundry application really quickly. So, let‘s move this application into the cloud.
Converting to a Cloud Foundry application
To convert the application, we will use one of the many small frameworks, a generic Buildpack for Cloud Foundry which is available on GitHub. To create a Cloud Foundry application with this build pack we will have to create 2 files named SourceyStart.sh and SourceyBuild.sh.
To move the application into the cloud, follow these steps:
1. Set up a basic Plack environment in the Cloud Foundry container.
To make your application work, tell your Cloud Foundry application builder how to create the correct Perl stack. This boils down to creating a SourceyBuild.sh file that contains a number of a “buildPerlModule” commands, per module you are using in your application that does not come with the standard Cloud Foundry environment.
For now, we will have to add the following:
buildPerlModule PSGI buildPerlModule Plack buildPerlModule Plack::Runner buildPerlModule Plack::Request buildPerlModule Plack::Response buildPerlModule Plack::Builder
2. Create the startup script for your application.
The “SourceyStart.sh” script containing the startup code for your application.
Please note that the script will be passed the port number on which to accept web requests. In our case we decide to go for something really simple and handle the Plack setup in a little Perl script:
#! /bin/sh echo "starting plackup" PERL5LIB="/home/vcap/app/sourcey/lib/perl:/home/vcap/app/sourcey/lib/perl5" ./app.pl --port $PORT
3. Create the Plack setup script and copy its content on your local machine.
Create the Plack setup script “app.pl” and with the PERL5LIB path set correctly this is no more difficult than just using making a copy of what is in the “plackup” script on your local machine.
#!/usr/bin/env perl use strict; use Plack::Runner; my $runner = Plack::Runner->new; $runner->parse_options(@ARGV); $runner->run;
4. Set the app requirements.
The last thing to do is tell the Cloud Foundry environment what the application requires from a memory perspective and how many instances you would want to run. You can do so by creating a file named “manifest.yml” which is obviously in YML format:
applications: - name: halloworld buildpacks: - https://github.com/oetiker/sourcey-buildpack disk_quota: 1G instances: 1 memory: 32M stack: cflinuxfs3 timeout: 60
In the example above, we run one instance of this app and give it a memory footprint of 32MB which should be fine for this small application.
You should now have 5 files in your application directory:
- app.psgi
- SourceyBuild.sh
- SourceyStart.sh
- app.pl
- manifest.yml
With these files, you are ready to set up a Cloud Foundry application.
Running the app
In the previous sections, we covered the necessary steps for building a simple “Hello World” and converting it into a Cloud Foundry application. Now we’ll show you how to push this app to a Cloud Foundry environment:
1. Set up a working Cloud Foundry environment.
In general terms that means you will have to install a piece of software that connects to an external environment.
In our particular case, the Cloud Foundry environment comes integrated into the IBM Cloud environment. For more information, read Installing the stand-alone IBM Cloud CLI.
Once you are logged in into the environment you will be able to use “ibmcloud cf <command>” to run any Cloud Foundry command against the IBM Cloud environment.
In other circumstances, you might have to set up your own Cloud Foundry environment which is most likely well documented.
2. Push the app to your Cloud Foundry environment
After you finish setting up your local Cloud Foundry environment, you can push your application by simply instructing the Cloud Foundry environment to use the manifest.yml and install the cloud application. To do so is as simple as “cf push” or in our case prepending “ibmcloud”.
As soon as you have done that you will see the lines of the application builder scroll by.
$ ibmcloud cf push Invoking ‘cf push’... Pushing from manifest to org Nexperteam / space digitalinvite as jan@nexperteam.be... Using manifest file /home/jan/projects/blog/webapp/manifest.yml Getting app info... Creating app with these attributes... + name: halloworld path: /home/jan/projects/blog/webapp buildpacks: + https://github.com/oetiker/sourcey-buildpack + disk quota: 1G + health check timeout: 60 + instances: 1 + memory: 64M + stack: cflinuxfs3 routes: + halloworld.eu-de.mybluemix.net Creating app halloworld... Mapping routes... Comparing local files to remote cache... Packaging files to upload... Uploading files... 130.33 KiB / 130.33 KiB [==========================================================] 100.00% 1s Waiting for API to complete processing files... Staging app and tracing logs... Cell e18fb5f1-d6fb-4e1d-b9f8-fcd13fa4b4df creating container for instance 0cb5c538-83bc-4808-ad10-e5974a3a4eb5 Cell e18fb5f1-d6fb-4e1d-b9f8-fcd13fa4b4df successfully created container for instance 0cb5c538-83bc-4808-ad10-e5974a3a4eb5 Downloading app package... Downloaded app package (130.3K) Environment - WORK_DIR=/home/vcap/tmp/sourcey.53 - BUILD_DIR=/tmp/app - APP_DIR=app - PREFIX=/home/vcap/app/sourcey - CACHE_DIR=/tmp/cache/final Downloading cpanminus --2020-09-18 11:25:01-- http://cpanmin.us/ Resolving cpanmin.us (cpanmin.us)... 151.101.66.217, 151.101.194.217, 151.101.2.217, ... Connecting to cpanmin.us (cpanmin.us)|151.101.66.217|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 302780 (296K) [text/plain] Saving to: ‘cpanm’ 250K .......... .......... .......... .......... ..... 100% 13.3M=0.01s 2020-09-18 11:25:01 (21.4 MB/s) - ‘cpanm’ saved [302780/302780] Successfully installed PSGI-1.102 1 distribution installed Successfully installed File-ShareDir-Install-0.13 Successfully installed Stream-Buffered-0.03 Successfully installed Devel-StackTrace-2.04 Successfully installed ExtUtils-Config-0.008 Successfully installed ExtUtils-InstallPaths-0.012 Successfully installed ExtUtils-Helpers-0.026 Successfully installed Module-Build-Tiny-0.039 Successfully installed TimeDate-2.33 Successfully installed Time-Local-1.30 (upgraded from 1.25) Successfully installed HTTP-Date-6.05 Successfully installed HTTP-Headers-Fast-0.22 Successfully installed Try-Tiny-0.30 Successfully installed Module-Build-0.4231 Successfully installed WWW-Form-UrlEncoded-0.26 Successfully installed Test-SharedFork-0.35 Successfully installed Test-TCP-2.22 Successfully installed URI-1.76 Successfully installed Cookie-Baker-0.11 Successfully installed Devel-StackTrace-AsHTML-0.15 Successfully installed IO-HTML-1.001 Successfully installed LWP-MediaTypes-6.04 Successfully installed Encode-3.07 (upgraded from 2.88) Successfully installed Encode-Locale-1.05 Successfully installed HTTP-Message-6.26 Successfully installed POSIX-strftime-Compiler-0.44 Successfully installed Apache-LogFormat-Compiler-0.36 Successfully installed Class-Inspector-1.36 Successfully installed File-ShareDir-1.116 Successfully installed Test-Deep-1.130 Successfully installed HTTP-MultiPartParser-0.02 Successfully installed Cpanel-JSON-XS-4.23 Successfully installed JSON-MaybeXS-1.004002 Successfully installed Hash-MultiValue-0.16 Successfully installed HTTP-Entity-Parser-0.24 Successfully installed Filesys-Notify-Simple-0.14 Successfully installed Plack-1.0047 36 distributions installed Plack::Runner is up to date. (undef) Plack::Request is up to date. (1.0047) Plack::Response is up to date. (1.0047) Plack::Builder is up to date. (undef) … Exit status 0 Uploading droplet, build artifacts cache... Uploading droplet... Uploading build artifacts cache... Uploaded build artifacts cache (9.8M) Uploaded droplet (10M) Uploading complete Cell e18fb5f1-d6fb-4e1d-b9f8-fcd13fa4b4df stopping instance 0cb5c538-83bc-4808-ad10-e5974a3a4eb5 Cell e18fb5f1-d6fb-4e1d-b9f8-fcd13fa4b4df destroying container for instance 0cb5c538-83bc-4808-ad10-e5974a3a4eb5 Waiting for app to start... name: halloworld requested state: started routes: halloworld.eu-de.mybluemix.net last uploaded: Fri 18 Sep 13:30:43 CEST 2020 stack: cflinuxfs3 buildpacks: https://github.com/oetiker/sourcey-buildpack type: web instances: 1/1 memory usage: 64M start command: PATH=$HOME/sourcey/bin:$PATH PERL5LIB='/home/vcap/sourcey/lib/perl5' ./SourceyStart.sh state since cpu memory disk details #0 running 2020-09-18T11:30:54Z 0.0% 0 of 64M 0 of 1G
Right at the top of the application builder lines, you find the URL that runs your web application. In our case it is https://halloworld.eu-de.mybluemix.net and visiting the location will give you a warm welcome.
In the next post, we will extend this application to do something more practical.
Drop me a note below with your thoughts and questions about building cloud applications and I’ll do my best to answer them in future posts.