PHP Deployment (GCP)

This is a short introduction to help you setup and deploy your PHP programs using Google Cloud Platform (GCP) Standard App Engine. For more information on GCP App Engine, please visit https://cloud.google.com/appengine/
(Please let me know if you find any errors or omissions in the document —Upsorn Praphamontripong, 29-September-2023)

Create a new project

Redeem and use your Google coupon. Do NOT enter your credit card. (If you have not received an email with the link to redeem a coupon, please see CS 4750 Collab's Announcement "Database server (and web server) options, and Google Cloud Platform coupon"). If more coupons are needed, please make a private post on Piazza. We will get you more coupons. Do NOT enter your credit card information.

  1. Assuming that you already have a Google account. Go to the Google Cloud Console and login to your account
  2. Click the "Select a project" dropdown icon (next to "Google Cloud Platform")

    dropdown to select a project

  3. Select  New Project

    dropdown to select a project

    This will prompt a screen allowing you to create a new project. Enter your  Project Name (e.g., cs4750db), be sure the  Billing account is associated with the Google coupon you redeemed. Then, click  CREATE.

    image showing how to create a new project

    Note: depending on how your account was set, you may be required to enter Location or Organization. Please select University of Virginia and proceed to create the project.


Configure the prerequisites

  1. Download and intall Cloud SDK
    • Download Cloud SDK based on your operating system
    • Extract the file. By default, a folder named  google-cloud-sdk  will be created in the same location where you extract the file
    • Use a terminal, run  ./google-cloud-sdk/bin/gcloud init  to initialize the SDK and configure your deployment environment.

      screen running gcloud init

      Enter  2  to create a new configuration.

      If you have previously configured the environment or project, you may see a screen with more configuration options as follows. Choose the appropriate choice.

      screen running gcloud init

      Enter configuration name (for example  cs4750db).

      screen running gcloud init

      You may be prompted to login to your GCP account. You may also be asked to give Cloud SDK permission to access your account. Please enter your GCP account information and allow the access.

      screen to grant access to GCP account

      If you have previously logged in to your GCP account, you may be asked to choose an account to associate with the configuration. Please choose the account you wish to use.

      screen to login to GCP account

      You may need to update you SDK.

      Once your account has been successfully logged in and the SDK has access to your account, you should see a list of your existing projects. Choose the cloud project where your PHP program(s) will be deployed.

      example screen to deploy php on GCP

      If this is the first time setting up the project on your machine, you may be asked to configure a default Compute Region and Zone. Please enter 6 for us-east4-a.

      example screen to configure Google Compute Engine Zone

      Later, you should see a message  Your Google Cloud SDK is configured and ready to use!.
    • You may need to manage and install additional Cloud SDK components. Use a terminal
      • Run  gcloud components list
      • Run  gcloud components install component_id to install the needed components (replace  component_id  with the following)
        • app-engine-php
        • cloud_sql_proxy — if you plan to use MySQL on GCP with your PHP program
      If you need to remove a component, use  gcloud components remove component_id.
  2. [Optional] Download and install Git

    Note: If you already have Git on your machine, please skip this step.

  3. [Assuming you are developing a PHP web app] Download and install PHP 7.4

    If you have already installed XAMPP that includes either PHP on your machine, you do not need to install PHP again. Please skip this step.

    The stable version of PHP that GCP App Engine supports is PHP 7.4. GCP App Engine appears to have some issues with PHP 8.1.

  4. [Optional] Download and install Composer. This can later be useful to manage dependencies.

    Note: If you already have Composer on your machine, please skip this step.


Deploy a PHP app

  1. Create a folder for your PHP app, assuming the folder is named  php-gcp.
  2. In the  php-gcp  folder, create a blank file named  helloworld.php. Paste the following contents in the file
    <?php echo "Hello World @^_^@" ?>
  3. Create Config file that will be used by GCP App Engine to deploy the app. In the  php-gcp  folder, create a blank file named  app.yaml  

    Paste the following contents in the file

    # Use the PHP 8.1 runtime
    runtime: php81
    
    # Defaults to "serve index.php" 
    entrypoint: serve helloworld.php
    
    # If your main page is index.php, comment the above entrypoint setting 
  4. Use a terminal, go to the  php-gcp  folder, run  gcloud app deploy

    If this is the first time you deploy your app, you may be asked to configure a default Compute Region. Select us-east4.

    example screen to configure service region

    Once the App Engine application has been created, you will be prompted with the service information (similar to the following image)

    example screen to deploy php on GCP

    Enter  y  to continue

    Once the deployment is completed, you should see a screen similar to the following

    example screen to deploy php on GCP

    Note the <url-to-your-app>. You will later use it to access your app via a web browser.

Troubleshooting:
If running  gcloud app deploy  results in  gcloud: command not found,  the classpath may not have been set properly. You may either (i) set a classpath pointing to your  google-cloud-sdk/bin  folder or (ii) run the command with an absolute path; for example (Mac users),  Users/path-to/google-cloud-sdk/bin/gcloud app deploy. (Thanks to Yu Du for the note)


Access an app

To access your app, you may run the command
    gcloud app browse

Or open a web browser and access your app using the URL obtained when you deployed the app. Your URL will be similar to one of the following:
    https://your-project-ID.appspot.com, or
    https://your-project-ID.uk.r.appspot.com.
In this example, the project ID is  cs4750db,  the target URL would be    https://cs4750db.appspot.com

Assuming your PHP contains the above sample code, you should see a screen similar to the following.

sample run hello world


Note: when running  gcloud app deploy  in the  php-gcp  folder, resources and config file in the folder will be used. That is, the current deployment is based on the folder in which you run  gcloud app deploy

For more example, create another folder outside of  php-gcp folder (assume the new folder is called  another-php-gcp) . Create a blank file named  simpleform.php. Paste the following contents in the file

<!DOCTYPE html>
<html>
<head>
  <title>PHP example</title>
</head>

<body>
  <form action="simpleform.php" method="post">
    <input type="text" name="yourname" /> <br/>
    <input type="submit" value="Submit" />
  </form>
  
<?php
$str = "Hello world"; 
if (isset($_POST['yourname']))
   $str = "You've entered ". $_POST['yourname'];
echo $str;  
?>

</body>
</html>    

In the  another-php-gcp  folder, create a config file  app.yaml. Paste the following contents in the file

# Use the PHP 8.1 runtime
runtime: php81

# Defaults to "serve index.php" 
entrypoint: serve simpleform.php

# If your main page is index.php, comment the above entrypoint setting 

Use a terminal, go to the  another-php-gcp  folder, deploy the app by running  gcloud app deploy

Access your app via a web browser, using the URL obtained when you deployed the app. Your URL will be similar to either  https://your-project-ID.appspot.com or https://your-project-ID.uk.r.appspot.com. In this example, the project ID is  cs4750db,  the target URL would be    https://cs4750db.appspot.com


Style an app

Modify simpleform.php, style the screen with bootstrap and simple CSS rules.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">    
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />    
  <title>PHP example</title>    
</head>

<body>
<div class="container">

  <h1>First PHP example</h1>
  <form action="simpleform.php" method="post">
    Your name: <input type="text" name="yourname" class="form-control" /> <br /> 
    <input type="submit" value="Submit" class="btn btn-primary" />
  </form>
  
<?php
$str = "Hello world"; 
if (isset($_POST['yourname']))
   $str = "You've entered ". $_POST['yourname'];
echo "<div style='font-style:italic; color:green'> $str </div>" ;  
?>

</div>
</body>
</html>

Deploy the app by running  gcloud app deploy

Access your app via a web browser, using the URL obtained when you deployed the app. Your URL will be similar to either  https://your-project-ID.appspot.com or https://your-project-ID.uk.r.appspot.com. In this example, the project ID is  cs4750db,  the target URL would be    https://cs4750db.appspot.com

If you only use a URL without file name to a default screen, you need to modify the  <form>  tag of  simpleform.php  to submit the form data to the current URL instead of hard-coding the destination with a string  "simpleform.php

<form action="<?php $_SERVER['PHP_SELF'] ?>" method="post">

Route multiple paths

If your app contains multiple PHP files, you need to set up a controller to redirect the user to a proper PHP file. The controller (so-called "front-controller") will be used to route all traffic to the proper PHP file.

Note: the front-controller design pattern is needed to deploy and map multiple PHPs on GCP.

  1. Suppose we want to provide a contact form, create a file named  contact.php  and add the following code to it.
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">    
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />    
      <title>PHP example</title>    
    </head>
    
    <body>
    <div class="container">
      <h1>Get in Touch!</h1>
      <div class="mb-2">   
        <input type="text" class="form-control" placeholder="Name" name="">
      </div>
      <div class="mb-2">
        <input type="email" class="form-control" placeholder="Email Address" name="email">
      </div>
      <div class="mb-2">
        <textarea class="form-control" rows="4"></textarea>
      </div>
      <div class="d-grid"> 
        <input type="submit" class="btn btn-secondary" value="Send" name="">
      </div>  
      
    </div>
    </body>
    </html>  
  2. Add the following code to  simpleform.php
    <a href="contact.php">contact.php</a>
  3. Create a blank file named  index.php  to be used as a front controller.
  4. Include the following code in your  index.php  to route all traffic to the specified PHP file. Be sure to replace the example file names (simpleform.php and contact.php) with the names of your PHP files.
    <?php
    switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
       case '/':                   // URL (without file name) to a default screen
          require 'simpleform.php';
          break; 
       case '/simpleform.php':     // if you plan to also allow a URL with the file name 
          require 'simpleform.php';
          break;              
       case '/contact.php':
          require 'contact.php';
          break;
       default:
          http_response_code(404);
          exit('Not Found');
    }  
    ?>
  5. Update the  app.yaml  so that the entry point is the front controller (index.php)
    # Use the PHP 8.1 
    runtime: php81
    
    # Defaults to "serve index.php" 
    # entrypoint: serve helloworld.php
    # entrypoint: serve simpleform.php
    
    # if main page is index.php, comment the above entrypoint setting line
    

Copyright © 2023 Upsorn Praphamontripong

Released under the Creative Commons License CC-BY-NC-SA 4.0 license.

Last updated 2023-09-29 21:49