Setting up Prince on EC2 with PHP

Bruce Lawson
8 min readJun 9, 2020

--

In our previous article, we showed you how to set up Prince on AWS Lambda using Node.js. However, not everyone wants to write JavaScript to produce PDFs from their website. So here we will use Prince with the most popular server-side scripting language, PHP. Prince is free for non-commercial use.

Part 1: creating an EC2 machine

First sign in to the AWS console.

We need to set up a new server, which will be a virtual machine in Amazon’s cloud; this collection of everybody’s virtual machines is called “EC2”. Amazon provide a wizard to help you set up this new server: under “Build a solution”, choose “Launch a virtual machine (with EC2)”.

You need to choose a Amazon Machine Image, or AMI: this is the operating system that your new server will run. Choose Ubuntu Server 18.04 LTS, ensure “64-bit (x86)” is selected, and choose Select.

Next choose an Instance Type. This depends on how much you plan to do on this machine; instance types describe how much memory and processing power your new server has. For now, choose a t2.micro, to experiment using AWS’s free plan.

Select “Review and Launch”.

On the Review Instance Launch screen, you can see the technical details of your instance and go back to change them if you want; for now, click Launch.

If you have not used EC2 before, you will need to create some keys so that you can connect to this machine. The AWS console will show you a window entitled “Select an existing key pair or create a new key pair”. If you already have EC2 experience, use whichever keypair you already have set up. If you do not, then create a new one: in the first dropdown, choose “Create a new key pair”. Name this as “Prince”, or some other name you find appropriate, and click “Download Key Pair”. This will download a private key file called Prince.pem. Store this file somewhere secure: it is what you will need shortly to connect to this new server. Once downloaded and stored, click Launch Instances.

This will start creating your new EC2 virtual machine, called an “instance”, and show you the Launch Status screen. On this screen, click View Instances to see the list of your EC2 instances. (If you want to at any time get back to this list of your instances, it is at https://console.aws.amazon.com/ec2/v2/home#Instances:, or you can get there by navigating to the AWS console (https://console.aws.amazon.com), then All services > Compute > EC2, then Instances in the left sidebar.)

On the instances list, you should be able to see the machine you have just created; in particular, the “Instance State” should be “running”. Select the machine with the checkbox on the left, and the bottom half of the screen should show details about this newly created instance. To connect to it, you need to know its name, which is listed as “Public DNS (IPv4)” under “Description”: it should look something likeec2-1-2-3-4.compute-1.amazonaws.com. Make a note of this name.

You can now establish an SSH connection to this machine, using the private key file from earlier. How to do this differs between OSes. In each of these commands, use the name of your own created machine and your own private key file as recorded above.

From Linux and MacOS: in a Terminal, ssh -i path/to/Prince.pem ubuntu@ec2–1–2–3–4-compute-1.amazonaws.com.

Note that you may need to set permissions on Prince.pem so that it is readable by you only: if you do not, then ssh may refuse to connect with an UNPROTECTED PRIVATE KEY FILE warning. To do so from a command line, this is chmod 600 path/to/Prince.pem.

From Windows, there are two options. You can use the free open-source PuTTY utility (see AWS’s instructions) or use the official OpenSSH For Windows 10 from Microsoft.

Ideally, you should confirm that you’re connecting to the right machine by checking the key fingerprints; when sshing into a machine, ssh says The authenticity of host ‘ec2–3–88–137–183.compute-1.amazonaws.com (3.88.137.183)’ can’t be established. ECDSA key fingerprint is SHA256:YPpS1tGqGMOkk7Q3EVxP/0xZvkDwJdEVYZnpu5xfcQQ. Are you sure you want to continue connecting (yes/no)?

Checking the key fingerprints is out of scope of this article (see AWS’s docs for detail); for now, confirm that you want to continue connecting.

Once you have made a successful SSH connection to the new machine, ensure it is up to date by running the following commands:

sudo apt update

sudo apt upgrade (say Yes if asked if you want to continue)

These may download new versions of the OS, or may not. If asked if you want to change any files, choose “Keep the locally installed version”.

You can now proceed to setting up this machine to run Prince.

Part 2: setting up the EC2 machine to run Prince and a web server

From the Prince download page, copy the link to the “Ubuntu 18.04 / 64-bit deb”. At time of writing this is https://www.princexml.com/download/prince_13.5-1_ubuntu18.04_amd64.deb but it may have changed when you read this.

In the ssh session, download that deb file to your EC2 instance with wget https://www.princexml.com/download/prince_13.5-1_ubuntu18.04_amd64.deb. Now install Prince:

apt install ./prince_13.5–1_ubuntu18.04_amd64.deb

(the ./ in front of package path is required).

Prince should now be installed: to confirm, enter prince --version, which should list something like:

Prince 13.5 Copyright 2002-2020 YesLogic Pty. Ltd. Non-commercial License

Next, install a web server: sudo apt install apache2 php.

The web server is now installed, but EC2 does not make it accessible from the outside world by default. To change this, we need to add a new inbound rule to the instance’s security group to allow HTTP traffic on port 80. To do this: in the instances list, select your instance, and look at “Security groups” under Description. This will list any security groups that this instance is part of; if you followed the above instructions, it will likely list launch-wizard-1, as well as links to show its inbound and outbound rules.

Click this security group name. This will take you to the Security Groups screen (also obtainable from Network & Security > Security Groups in the left sidebar). Find the security group you care about in the list (with the appropriate Security group name).

Click on the blue “security group ID” link to see the page for this particular security group, and under “Inbound Rules” choose “Edit inbound rules”.

On the “Edit inbound rules” screen you will create a new inbound rule, to allow HTTP requests on port 80 to get to the machine. There should already be one rule present, to allow SSH connections on port 22; this is how your existing SSH connection is allowed. Click “Add rule” to add a second rule, then choose “HTTP” under Type. Under Source, ensure Custom is selected in the first drop down, and choose “0.0.0.0/0” in the second; this will allow network connections from anywhere to this machine. Finally, click “Save Rules” to add this new permission.

Note: you can restrict network traffic to this machine by entering a specific IP address or specific range under Source, if you know that requests to this device will only come from certain specific places; this will help to improve security.

At this point, your web server should be accessible to the outside world. Test it by visiting http://ec2-1-2-3-4.compute-1.amazonaws.com (using your machine's Public DNS address, as recorded above), and you should see the Apache2 Ubuntu Default Page.

Now that Prince is working, you can build a simple PHP interface to access it!

Part 3: using Prince via PHP

The Prince project have provided a PHP wrapper for Prince itself. To quickly fetch this, in the SSH connection to your instance, say wget https://github.com/yeslogic/prince-php-wrapper/raw/45fb4575bacb826d9db11e17f9b0a9033a68110f/prince.php.

Web server content on the machine is located in the /var/www/html folder. Move prince.php to there so that it is accessible, with sudo mv prince.php /var/www/html/.

We now need a very simple PHP page to receive HTML sent over HTTP POST, and then convert that HTML to PDF with Prince. An example PHP page might look as follows:

<?php
include 'prince.php';
if (isset($_FILES["html"])) {
$input_html_file = $_FILES['html']['tmp_name'];
$prince = new Prince('/usr/bin/prince');
ob_start();
$result = $prince->convert_file_to_passthru($input_html_file, $msgs);
if ($result) {
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="output.pdf"');
ob_end_flush();
die();
} else {
http_response_code(500);
echo "<html><body>Errors processing HTML into PDF:<br>";
foreach($msgs as $err) { echo htmlentities($err[2]) . "<br>"; }
}
} else {
http_response_code(400);
echo "Error: no input file provided.";
}
?>

Create this file on the EC2 instance with simple text editor nano like this: sudo nano /var/www/html/convert.php and paste in the text above. Use Ctrl-X to save and exit. Note that the /var/www folder is writable by the root user (hence using sudo) but readable by the webserver user, www-data.

PHP takes care of deleting the uploaded HTML after conversion.

To test that this works, create a simple HTML form that POSTs uploaded HTML content to the page. Remove the existing “Apache2 Ubuntu Default Page” index.html file with sudo rm /var/www/html/index.html, then create a new index file with sudo nano /var/www/html/index.html and add the following text:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<form method="POST" action="convert.php" enctype="multipart/form-data">
<input type="file" name="html">
<input type="submit">
</form>
</body>
</html>

This (very) simple HTML form should allow you to upload an HTML file and get its contents back as a PDF, converted with Prince. Visit it at http://ec2-1-2-3-4.compute-1.amazonaws.com (using your above remembered address) and upload an HTML file: you should receive a PDF-converted version of that file back.

And there you are — you now have Prince running ‘serverlessly’, for a fraction of the costs of maintaining your own server.

The Prince team are grateful to Martin Beeby of AWS, and Stuart Langridge for their assistance with this article.

--

--

Bruce Lawson

Web geek. Open Standards/ Open Source consultant. Groovy cat.