Community Blog How to Develop Function Compute with WordPress Applications

How to Develop Function Compute with WordPress Applications

In this article, you will learn how to develop WordPress applications quickly on Function Compute.

By Yi Xian

In this article, you will learn how to develop WordPress applications quickly on Function Compute. But before we get into the main part of this article, let's take a look at several important concepts mentioned in this article:

Background Information

First, one important concept is Alibaba Cloud's Function Compute, which is an event-driven service that allows users to write and upload code without having to manage server health or consider some other factors. Function Compute prepares and auto scales to the appropriate amount of computing resources to run user code. The user only pays for the resources required to run their code.

Next, there's Fun, which is a deployment tool for serverless applications. It helps you manage resources, such as Function Compute, API Gateway, and Log Service. You can use Fun to develop, build, and deploy resources by describing specified resources in the template.yml file.

And then there's also Fun Local, which is a sub-command of Fun. You can use it directly through the fun local command. The Fun Local tool can fully simulate and run the functions in Function Compute locally and provides the single-step debugging feature, which makes up for Function Compute shortcomings when compared with traditional application development experience, and provide users with a new way to solve Function Compute problems.

Note: The tips described in this article require that you are using Fun version 2.8.0 and later.

Create a Fun Project

Create a directory as the root directory of the Fun project, and then create an index.php to write the function code:

use RingCentral\Psr7\Response;

function startsWith($haystack, $needle) {
    $length = strlen($needle);
    return (substr($haystack, 0, $length) === $needle);

function handler($request, $context): Response{
    $uri    = $request->getAttribute("requestURI");
    $uriArr = explode("?", $uri);

    // default php / or /wp-admin/
    if (preg_match('#/$#', $uriArr[0]) && !(strpos($uri, '.php'))) {
        $uriArr[0] .= "index.php";
        $uri = implode($uriArr);
        if (startsWith($uri, "/2016-08-15/proxy/share/wp-func/wp-admin/")) {
            // wordpress admin entrypoint
            $request = $request->withAttribute("requestURI", $uri);

    $proxy    = $GLOBALS['fcPhpCgiProxy'];
    $root_dir = '/mnt/www';
    //php script
    if (preg_match('#\.php.*#', $uri)) {
        $format = '%s.%s.fc.aliyuncs.com';
        $host   = sprintf($format, $context['accountId'], $context['region']); // maybe user define domain
        $resp   = $proxy->requestPhpCgi($request, $root_dir, "index.php",
            ['SERVER_NAME' => $host, 'SERVER_PORT' => '80', 'HTTP_HOST' => $host],
            ['debug_show_cgi_params' => false, 'readWriteTimeout' => 15000]
        return $resp;
    } else {
        // static files, js, css, jpg ...
        $filename = $root_dir . explode("?", $uri)[0];
        $filename = rawurldecode($filename);
        $handle   = fopen($filename, "r");
        $contents = fread($handle, filesize($filename));
        $headers = [
            'Content-Type'  => $proxy->getMimeType($filename),
            'Cache-Control' => "max-age=8640000",
            'Accept-Ranges' => 'bytes',
        return new Response(200, $headers, $contents);

Then, create a template.yml file:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
    Type: 'Aliyun::Serverless::Service'
      Description: 'fc wordpress test'
        - AliyunECSNetworkInterfaceManagementAccess
        VpcId: 'vpc-bp12hm92gdpcjtai7ua82'
        VSwitchIds: [ 'vsw-bp1gitru7oicyyb4uiylj' ]
        SecurityGroupId: 'sg-bp1243pi65bw4cjj4bks'
        UserId: -1
        GroupId: -1
          - ServerAddr: '012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com:/'
            MountDir: '/mnt/www'

      Type: 'Aliyun::Serverless::Function'
        Handler: index.handler
        Runtime: php7.2
        CodeUri: './index.php'
        Timeout: 100
        http-test: # trigger name
          Type: HTTP # http trigger
              AuthType: ANONYMOUS
              Methods: ['GET', 'POST', 'PUT']

In the template.yml file, VPC service, NAS service, and HTTP trigger are described. At this point, the function has been developed. Before releasing it online, we need to debug it locally.

Function Compute can be simulated and started locally by executing the fun local start command:


When opening the prompt URL, you will obtain an error prompt:


This is because WordPress has not been installed. We need to install WordPress on the directory where the NAS is mounted. For fun local support for NAS, see here. We need to perform the following steps to allow the function to access the WordPress application:

  1. Download WordPress.
  2. Decompress the downloaded WordPress.
  3. Copy the content of the decompressed WordPress to the locally simulated NAS directory.

For this project, the locally simulated NAS directory is: .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/. This directory is mounted to the /mnt/www of the container when the function is running. The function can directly access this directory.

For the WordPress application, we need to create subdirectories under .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/ in sequence: 2016-08-15/proxy/share/wp-func.

This can be done directly by running the following command:

mkdir -p .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/2016-08-15/proxy/share/wp-func

Then, copy the content of the decompressed WordPress, which can also be done by running a similar command:

cp -r wordpress/ .fun/nas/012194b28f-ujc20.cn-hangzhou.nas.aliyuncs.com/2016-08-15/proxy/share/wp-func/

After the operation is complete, we can directly refresh the page without restarting the service.

When the page is opened, the configuration wizard will be displayed. Then, follow the wizard prompts to configure the database and user information.

Know that, if RDS is used in local development, you need to apply for an public IP address, and set the IP whitelist to However, indicates that any device is allowed to access the RDS instance, so this is not recommended unless it is a test. It is better to use MySQL for development locally. The function runs in the Docker container, and the network environment is isolated from the host, so the local MySQL needs to be configured to allow access from any IP address.

0 0 0
Share on

Alibaba Cloud Serverless

97 posts | 7 followers

You may also like


Alibaba Cloud Serverless

97 posts | 7 followers

Related Products

  • Deploy NVIDIA on Alibaba Cloud

    Fueled by the insatiable demand for better 3D graphics, and the massive scale of the gaming market, NVIDIA has evolved the GPU into a computer brain at the exciting intersection of virtual reality, high performance computing, and artificial intelligence.

    Learn More
  • Serverless Workflow

    Visualization, O&M-free orchestration, and Coordination of Stateful Application Scenarios

    Learn More
  • Serverless Application Engine

    Serverless Application Engine (SAE) is the world's first application-oriented serverless PaaS, providing a cost-effective and highly efficient one-stop application hosting solution.

    Learn More
  • Function Compute

    Alibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.

    Learn More