Cloud Images with ZendPHP
April 26, 2022

Cloud Images With ZendPHP

Modernization
DevOps

ZendPHP is a commercial distribution of the PHP runtime, built with cloud and container orchestration in mind.

In this blog, we take a look at cloud images with ZendPHP and how they make deployment of PHP applications simple and consistent.

Moving PHP to the Cloud

Knowing that ZendPHP was built with cloud orchestration in mind, where can you get ZendPHP today?

We currently have images in each of:

  • Amazon Web Services (AWS)
  • Microsoft Azure
  • Google Cloud Platform (GCP)

In each cloud platform, we provide machine images with PHP-FPM-enabled ZendPHP installs for each of RHEL 8, Debian 10, and Ubuntu 20.04, with additional operating systems on their way. Each operating system has image variants for Apache and nginx, allowing you to choose the web server with which you are most familiar.

While we initially pin the images to the current, most stable PHP version (the one still getting security patches, but no longer getting bugfixes; 7.4 at the time of writing), you can choose from any of the PHP versions we currently ship.

When you first spin up the machine, a virtual host is enabled with the document root pointing to /var/www/, allowing you to immediately deploy an application.

Managing Your Cloud Machine Image

To simplify management of your machine image, and reduce differences between operating systems, we now provide a management script, zendphpctl. Additionally, we provide tools for managing vhosts and mapping specific PHP-FPM versions to specific vhosts.

zendphpctl

At the time of writing, this script is not yet present in our cloud images, but will be in upcoming releases. You can test your image using the command which zendphpctl; if the system cannot find it, you will need to download it. For instructions on installing the script, visit our zendphpctl documentation.

Let's say your application is currently tested against PHP 7.2. You can use zendphpctl to install that version, with PHP-FPM:

$ zendphpctl php-install 7.2
$ zendphpctl fpm-install 7.2

You can then make it the default version:

$ zendphpctl php-set-default 7.2

What if you need additional extensions, such as intl, gd, mysql, and redis?

$ zendphpctl ext-install intl gd mysql redis

You can even use it to install PECL extensions:

$ zendphpctl ext-install timezonedb

Finally, assuming you have configured an editor (such as nano, vim, or emacs), you can use the tool to spawn an editor to edit your configuration:

$ zendphpctl php-config

Or if you want to edit the FPM configuration:

$ zendphpctl fpm-config

If at any time you need a list of available commands, run the tool without any arguments; you can also get help for individual commands by passing the --help flag.

$ zendphpctl ext-install --help

Managing Web Server Virtual Hosts

Each of Apache and nginx have virtual host (vhost) capabilities, but each configures them in very different ways. To make it possible for you to automate setup and configuration of vhosts across different web servers, we provide a script called zendphp-vhost.

By default, when creating a vhost, the tool will create it with TLS enabled, and utilize Let's Encrypt to provision a TLS certificate for you. This ensures that the services you create are immediately secured.

When you first startup your machine, it defines a "default" vhost. Let's change it to reflect the actual domain your vhost will answer to; in this example, we'll use "zendphp.example.org":

$ zendphp-vhost chgname default zendphp.example.org

This will change the vhost name in the configuration, and request the TLS certificate. Your document root will remain in /var/www.

Let's say instead you want to create a new domain, and remove the "default". You can do that in two steps:

$ zendphp-vhost add zendphp.example.org
$ zendphp-vhost remove default

What if you're running multiple nodes behind a load balancer, which will take care of the TLS negotiation? Create your vhost and indicate it will be operating on port 80 with HTTP:

$ zendphp-vhost add zendphp.example.org 80 http

For more information on managing vhosts with zendphp-vhost, visit our documentation.

Choosing a PHP Version to Use With a vhost

What if you have installed a different version of PHP, and want to use that with your vhost? The zendphp-switch script will help you here:

$ zendphp-switch to 7.2 zendphp.example.org

This allows you to switch between any PHP-FPM you have installed, and ensures the vhost is configured correctly to use that version.

Creating Custom Cloud Images

One way you can automate your deployments is to create custom machine images based on the official ZendPHP images we provide. The best way of doing this is using Packer.

In this example, we'll demonstrate creating an AWS machine image that uses PHP 7.2 for a custom Apache vhost, with our own application files already present. We'll assume that the file "app.tgz" is located in the working directory, and contains an application wherein its "public" subdirectory should be the document root.

First, we will create a script for setting up our instance, called setup.sh:

#!/bin/bash

set -e

# Install PHP 7.2 with PHP-FPM, intl, gd, mysql, and redis
echo "Installing PHP 7.2"
zendphpctl php-install 7.2
zendphpctl fpm-install 7.2
zendphpctl php-set-default 7.2
zendphpctl ext-install intl gd mysql redis

# Install application
echo "Installing the application source"
sudo mkdir -p /var/local/app
cd /var/local/app
sudo tar xzf /tmp/app.tgz
sudo chown -R www-data.www-data /var/local/app

# Remove the default /var/www directory, and symlink it to our application's public dir:
echo "Symlinking application public directory to vhost directory"
rm -rf /var/www
{
    cd /var
    ln -s /var/local/app/public www
}

# Switch the default vhost to PHP 7.2
echo "Switching vhost to PHP-FPM 7.2"
zendphp-switch to 7.2 default

echo "Restarting Apache"
sudo systemctl start php-fpm7.2-zend
sudo systemctl restart apache

With that in place, we can now define our Packer build script. Packer uses the HCL Configuration Language, which is a declarative language reminiscent of Lua. The following is an example that will work with our setup.sh script and our app.tgz archive to describe the steps to build an image for AWS.

packer {
  required_plugins {
    amazon = {
      version = ">=1.0.0"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

variable "region" {
  description = "AWS region in which to build and deploy"
  type        = string
  default     = "us-east-2"
}

variable "instance_type" {
  description = "EC2 instance type to use (defaults to t2.micro)"
  type        = string
  default     = "t2.micro"
}

locals {
  timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

source "amazon-ebs" "zendphp" {
  ami_name      = "zendphp-demo-${local.timestamp}"
  instance_type = var.instance_type
  region        = var.region
  source_ami_filter {
    filters = {
      # Find a ZendPHP image, using *ZendPHP*{DISTRO} # {VERSION}*{Apache|Nginx}*(BYOL*)?
      # Examples:
      #   - *ZendPHP*Debian 10*Apache*
      #   - *ZendPHP*Centos 8*Nginx*
      #   - *ZendPHP*Ubuntu 20.04*Apache*BYOL
      description         = "*ZendPHP*Ubuntu 20.04*Apache*BYOL*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["679593333241"]
  }
  ssh_username = "ubuntu"
  tags         = {
    Extra = "zendphp:ubuntu-20.04"
  }
}

build {
  sources = ["source.amazon-ebs.zendphp"]

  provisioner "file" {
    source      = "./app.tgz"
    destination = "/tmp/app.tgz"
  }

  provisioner "shell" {
    script = "./setup.sh"
  }
}

From here, we can then build an image. First, run the Packer init command:

$ packer init .

Then build the image:

$ packer build --var "region={AWS_REGION}" --var "instance_type={INSTANCE_TYPE}" images

You will need to substitute in the appropriate AWS region and EC2 instance type in the above command. Once completed, you will see this image available in your list of available AMIs (Amazon Machine Instances) under the AWS EC2 console.

Deployment Made Easy With ZendPHP Cloud Images

Deploying a PHP application in the cloud includes a lot of variables:

  • The operating system and version.
  • Knowing which PHP version is available on that OS and version.
  • Knowing which web servers are available, and how to install and configure them.
  • Knowing how to setup and configure PHP-FPM with your web servers.
  • Knowing how to setup your virtual host.
  • Knowing how to provision an SSL certificate, if needed.
  • And more!

The goal of ZendPHP cloud images is to make these things simple and consistent, and to remove the differences between how different operating systems and web servers work so that you can focus on getting your application deployed.

Tools such as zendphpctl, zendphp-vhost, and zendphp-switch make your job easier, and tools like Packer allow you to customize your images to include your application configuration so that they are ready to deploy immediately.

Get Started Now

What are you waiting for? Deploy YOUR PHP application in the cloud today using ZendPHP!

Speak With a PHP Expert   Start Free Trial