In the previous chapters we discussed several frameworks and libraries for facilitating the development of web applications. In this chapter, we focus on deploying such a web application. While doing so, we will try to answer some questions such as: which operating system should I use, how do I run my application, how do I ensure my application will be restarted after a reboot or a crash, and how do I log data.
The easiest and fastest way to host your application is to host it in the cloud.
PharoCloud, for example, proposes pre-packaged solutions (including Seaside, Pier and database support) as well as the possibility to use your own Pharo image. You could start very quickly from there but you do not have full control of your Pharo stack. It is however enough in most cases as PharoCloud manages the defaults for you.
There are many other cloud providers including Amazon AWS, Openshift, OVH and Microsoft Azure. Many Pharo users use DigitalOcean as it is both simple and cheap. Choose your cloud provider according to your needs.
In the rest of this chapter, we detail how to setup a server to host a Pharo web application.
Many Pharo developers use Mac OS X to develop their applications but it is not a popular solution for a production deployment due to a lack of dedicated Apple server hardware. A popular deployment OS is GNU/Linux. Deploying on Windows is a bit more complex and less supported by cloud providers.
There are many Linux distributions to choose from. If you restrict your choice to well-known free open-source distributions, competitors are Centos, Debian and Ubuntu. Most distributions will do the job, choose the most appropriate for you. A long-term support (aka., LTS) version is a good option if you do not want to update your operating system too often. The Pharo Virtual Machine (VM) comes pre-packaged for some distributions. For other distributions, you will have to compile the VM sources yourself. Pay attention that the Pharo VM is still 32bits as of early 2016 and you will have to install 32-bit libraries on your 64-bit Operating System.
The best option to obtain a clean image to deploy is to start from a fresh stable pharo image and to install the required packages through your application's Metacello configuration (read more in the Deep into Pharo book) and the command line handler. The configuration has to explicitely describe all dependencies used in your application.
First, create a copy of the clean image with your application name:
Then, install your dependencies:
After loading all necessary code, the
config option will also save the image so that the image now permanently includes your code.
To make sure that your deployment image is reproducible, the best approach is to create a Continuous Integration job that automatically produces clean deployment-ready images of your application.
When you have a Pharo image with your application inside, the next step is to start the application. To make this process reproducible, it is recommended to create a dedicated file (e.g., named
myapp.st) with the instructions needed to start your application. Here is an example of a script used to start a web application using Zinc.
This script starts an instance of the Zinc Web Server on
localhost on the port 8080 and stores it as the default instance. It configures the Zinc instance to log on the standard output and changes the default root (
/) handler to redirect to your new
/image web app. The
MyFirstWebApp class is from chapter Small Web Application, it handles HTTP requests by implementing the
You can test the startup script like this:
Ctrl-c to kill the server.
In Unix systems, init scripts are used to automatically start services when the server reboots and to monitor the status of these services. These scripts typically have a
start command, a
stop command and a
status command (some init scripts have more than these 3 commands). Your application's init script should be configured to be automatically executed when the server restarts. This init script is typically placed in the /etc/init.d directory.
You can find a template for such an init script in
the GitHub pharo deployment scripts repository, named
pharo-service-script.sh. Give this script the name of your application. This script is derived from the template provided by the Ubuntu distribution in
In the same repository, the
pharo-run-script.sh is another useful script. It runs a Pharo image with a pre-defined Smalltalk script file to evaluate (i.e. the
myapp.st you wrote above). You may need to edit this file to configure the Pharo VM path and options. To use this script, create a folder with your application name myapp, then copy the
pharo-run-script.sh script into this folder with name myapp as well. Give the script execution permissions:
chmod a+x ./myapp.
You should end with a file hierarchy like this one:
When the file hierarchy is ready, you can start your application by executing the
./myapp script or by using the init script at the command line by executing
service myapp start.
When the Pharo image crashes (which will happen), there must be a way to automatically recover from this crash. For this to work, the application data must be backed up, there must be a way to know when the application has crashed, and there must be a way to automatically restart the application.
To avoid data loss, the simplest solution is to make your image stateless: if your image crashes, no data should be lost because no data is in the image. If your application requires persistent data (e.g., user accounts), the best is to use a database (e.g., PostgreSQL, MongoDB). You must then make sure that your database is backed up properly.
To automatically restart your application when it crashes, there must be a way to detect that it has crashed. With a standard operating system's init script such as the one described above, you can use the
status command to detect if Pharo is running or not. We will later discuss how to handle a frozen Pharo.
A simple solution to both monitor your application and take appropriate actions (e.g., restart) is to use the monit utility. In the remainder of this section we will show how to configure monit.
You can first activate the embedded HTTP dashboard of monit. This monit configuration, only allows local connections with a dedicated username and password pair.
Apply the new configuration:
To connect from a different place than localhost, use an SSH tunnel. For example, if the server running both your application and monit is named
myserver.com, execute the following to connect to your server and open a local port:
Keep the SSH connection open, and browse http://localhost:2812 to display the monit dashboard.
If you want notifications from monit, you need to configure email settings so that monit can send emails. Edit the monit configuration file again and add a line to set the mail server:
For more monit configuration options, refer to the monit documentation.
Configuration files related to an application (or a service) should be put into the
/etc/monit/monitrc.d directory (which is more modular than putting everything in the core configuration file). To enable a configuration just symlink it to
We will first enable a pre-defined configuration for SSH.
Warning: default configurations for well-known services are provided by monit but may require some adaptations (e.g., wrong path to the PID file).
To check for errors, you may need to run monit in verbose mode:
and check the monit error log, by default in
Application-specific configuration files must be added to the
/etc/monit/monitrc.d directory. Create a new
myapp file in this directory:
With this in place, when a problem occurs, the alert instruction makes sure
email@example.com is notified by email. The kind of monitoring is described with the check command. We ask monit to check a given PID file. If there is no PID or no process associated to the PID, monit will start the program with the given instruction. The last instruction prevents infinite loops if there is a problem with the script.
The following then activates the monitoring of myapp:
At this point, you have ensured you have a running Pharo image at any time.
A Pharo image may be running, i.e. the process is alive, but not responding to HTTP requests. In such cases, your application is unusable. This unresponsive state can be verified by sending a simple HTTP request and checking for the response. We can ask monit to monitor your web server by doing regular checks to a predifined URL and validating the HTTP response content:
This configuration will try to connect to the
/ping URL on localhost. If monit can not connect, or no answer arrives before 10 seconds, or the content is not exactly
pong, monit will restart the application.
You may also want to monitor Apache if there is an Apache server in front of your application. You can do that by adapting the already existing
apache2 monit configuration file:
Activate the Apache monitoring and reload the monit configuration:
You are done! Your Pharo aplication is now monitored.
It is a good idea to put a web server like Apache or Nginx in front of a Pharo web application. Mature web servers fully implement standards and commoditized functionalities, e.g. virtual host handling (multiple domains on the same IP address), URL rewriting, etc. They are also more stable, have built-in mechanisms for binding to privileged ports below 1024 as root and then executing as a non-privileged user, and are more robust to attacks. They can also be used to serve static content and to display a maintenance page.
Here is a simple Apache configuration that can be used to redirect the incoming internet traffic on the default HTTP port (80) to your Pharo web application running on the local interface on the port 8080.
The first section declares the full server name (including the domain), the second one activates the proxy to forward the traffic to your Pharo web application, and the last one creates dedicated log files.
The following configuration also redirects the incoming traffic to the default HTTP port (80) of your Pharo web application running on the local interface on the port 8080.
With this simple configuration, you will get a more secure and flexible configuration of your web application.
In this chapter we have seen how to deploy a Pharo web application. We presented places where to deploy and gave insights as to which operating system to use. We then talked about how to deploy and run a Pharo web application. Lastly we discussed how to monitor Pharo with monit and putting a HTTP server in front of the web application.
This chapter ends the Enterprise Pharo book. We hope you enjoyed learning about this set of libraries and frameworks, and that they prove useful for you. We wish you success!