Running the PHP Bookshelf app on Compute Engine

This tutorial shows how to run the PHP Bookshelf sample app on Compute Engine. Follow this tutorial to deploy an existing PHP web app to Compute Engine. You should work through the Bookshelf app documentation as part of the tutorial for the App Engine standard environment.

Objectives

  • Deploy the Bookshelf sample app to a single Compute Engine instance.
  • Scale the app horizontally by using a managed instance group.
  • Serve traffic by using HTTP load balancing.
  • Respond to traffic changes by using autoscaling.

Costs

このチュートリアルでは、以下の課金対象の Google Cloud Platform コンポーネントを使用します。

料金計算ツールを使用して、予測される使用量に基づき、費用の見積もりを出すことができます。 GCP を初めてご利用の場合は、無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

Before you begin

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Google Cloud Platform プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  3. Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

  4. Cloud Datastore, Cloud Storage, and Cloud Pub/Sub API を有効にします。

    APIを有効にする

  5. Cloud SDK をインストールして初期化します。
  6. Install PHP and install Composer.

Initializing Cloud Datastore

The Bookshelf app uses Cloud Datastore to store book data. To initialize Cloud Datastore in your project for the first time, follow these steps:

  1. In the Google Cloud Platform Console, open the Datastore page.

    Open Cloud Datastore

  2. On the Settings and utilities menu, select Preferences.

  3. Under User preferences, set the Language & region for your datastore, and then click Save.

  4. When you reach the Create an Entity page, close the window.

The Bookshelf app is ready to create entities on Cloud Datastore.

Creating a Cloud Storage bucket

The following instructions detail how to create a Cloud Storage bucket. Buckets are the basic containers that hold your data in Cloud Storage.

  1. In your terminal window, create a Cloud Storage bucket, where [YOUR_BUCKET_NAME] represents the name of your bucket:

    gsutil mb gs://[YOUR_BUCKET_NAME]
  2. To view uploaded images in the Bookshelf app, set the bucket's default access control list (ACL) to public-read:

    gsutil defacl set public-read gs://[YOUR_BUCKET_NAME]

Cloning the sample app

The sample app is available on GitHub at GoogleCloudPlatform/getting-started-php.

  1. Clone the repository:

    git clone -b steps https://github.com/GoogleCloudPlatform/getting-started-php.git
    
  2. Go to the sample directory:

    cd getting-started-php/optional-compute-engine
    

Configuring the app

  1. Copy the settings.yml.dist file:

    cp config/settings.yml.dist config/settings.yml
    
  2. Open config/settings.yml for editing.

  3. Replace [YOUR_PROJECT_ID] with your GCP project ID.

  4. Set the value of bookshelf_backend to datastore.

  5. Save and close settings.yml.

Running the app on your local computer

  1. Install dependencies:

    composer install
    
  2. Start a local web server:

    php -S localhost:8000 -t web
    
  3. In your browser, enter this address:

    http://localhost:8000

  4. Optional: To stop the local web server, press Control+C.

Deploying to a single instance

This section walks you through running a single instance of your app on Compute Engine.

Single-instance deployment

Push your code to a repository

You can use Cloud Source Repositories to create a Git repository in your project and upload your app's code there. Your instances can then pull the latest version of your app's code from the repository during startup. Using a Git repository is convenient because updating your app doesn't require configuring new images or instances; just restart an existing instance or create one.

If this is your first time using Git, use git config --global to set up your identity.

  1. In the GCP Console, create a repository:

    Create repository

  2. Push your app's code to your project's repository, where [YOUR_PROJECT_ID] is your GCP project ID and [YOUR_REPO] is the name of your repository:

    git commit -am "Updating configuration"
    git config credential.helper gcloud.sh
    git remote add cloud https://source.developers.google.com/p/[YOUR_PROJECT_ID]/r/[YOUR_REPO]
    git push cloud master
    

Initialize an instance by using a startup script

Now that Compute Engine instances can access your code, you need a way to instruct your instance to download and run your code. An instance can have a startup script that runs whenever the instance is started or restarted.

The entire startup script is defined in gce/startup-script.sh.

# Install PHP and dependencies from apt
apt-get update
apt-get install -y git nginx mongodb-clients php5 php5-fpm php5-mysql php5-dev php-pear pkg-config
pecl install mongodb

# Enable the MongoDB PHP extension
echo "extension=mongodb.so" >> /etc/php5/mods-available/mongodb.ini
php5enmod mongodb

# Install Composer
curl -sS https://getcomposer.org/installer | \
    /usr/bin/php -- \
    --install-dir=/usr/local/bin \
    --filename=composer

# Fetch the project ID from the Metadata server
PROJECTID=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")

# Get the application source code
git config --global credential.helper gcloud.sh
git clone https://source.developers.google.com/p/$PROJECTID /opt/src -b master
ln -s /opt/src/optional-compute-engine /opt/app

# Run Composer
composer install -d /opt/app --no-ansi --no-progress

First, the script installs and configures system libraries required for this app, including PHP, the MongoDB PHP extension, Composer, and NGINX. Then it clones the app's source code from Cloud Source Repositories and installs dependencies.

# Fetch the application config file from the Metadata server and add it to the project
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/project-config" \
  -H "Metadata-Flavor: Google" >> /opt/app/config/settings.yml

The app's YAML configuration, including project secrets, is fetched from the compute metadata server. This file is pushed to the metadata server when the compute instance is created.

# Disable the default NGINX configuration
rm /etc/nginx/sites-enabled/default

# Enable our NGINX configuration
cp /opt/app/gce/nginx/bookshelf.conf /etc/nginx/sites-available/bookshelf.conf
ln -s /etc/nginx/sites-available/bookshelf.conf /etc/nginx/sites-enabled/bookshelf.conf
cp /opt/app/gce/nginx/fastcgi_params /etc/nginx/fastcgi_params

# Start NGINX
systemctl restart nginx.service

The NGINX configuration for this app is installed by using gce/nginx/bookshelf.conf, and NGINX is started.

# Install Fluentd
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash

# Enable our Fluentd configuration
cp /opt/app/gce/fluentd/bookshelf.conf /etc/google-fluentd/config.d/bookshelf.conf

# Start Fluentd
service google-fluentd restart &

Finally, the script installs and configures the Logging agent. This step ensures the logging added earlier in this tutorial works as expected.

Create and configure a Compute Engine instance

  1. Create a Compute Engine instance. This command creates an instance, allows it to access GCP services, and runs your startup script. The instance name is my-app-instance.

    Linux/macOS

    gcloud compute instances create my-app-instance \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --machine-type=g1-small \
        --scopes userinfo-email,cloud-platform \
        --metadata app-location=$BOOKSHELF_DEPLOY_LOCATION \
        --metadata-from-file startup-script=gce/startup-script.sh \
        --zone us-central1-f \
        --tags http-server
    

    Windows

    gcloud compute instances create my-app-instance ^
        --image-family=debian-9 ^
        --image-project=debian-cloud ^
        --machine-type=g1-small ^
        --scopes userinfo-email,cloud-platform ^
        --metadata-from-file startup-script=gce/startup-script.sh ^
        --zone us-central1-f ^
        --tags http-server
    

  2. Check the progress of the instance creation.

    gcloud compute instances get-serial-port-output my-app-instance --zone us-central1-f
    

    When the startup script completes, the output displays Finished running startup script.

  3. Create a firewall rule to allow traffic to your instance.

    Linux/macOS

    gcloud compute firewall-rules create default-allow-http-8080 \
        --allow tcp:8080 \
        --source-ranges 0.0.0.0/0 \
        --target-tags http-server \
        --description "Allow port 8080 access to http-server"
    

    Windows

    gcloud compute firewall-rules create default-allow-http-8080 ^
        --allow tcp:8080 ^
        --source-ranges 0.0.0.0/0 ^
        --target-tags http-server ^
        --description "Allow port 8080 access to http-server"
    

  4. Get the external IP address of your instance.

    gcloud compute instances list
    
  5. To see the app running, go to http://[YOUR_INSTANCE_IP]:8080, where [YOUR_INSTANCE_IP] is the external IP address of your instance.

Manage and monitor your instance

To manage and monitor your instance, use the GCP Console.

  • To view the running instance and connect to it by using ssh, in the GCP Console, go to the VM instances page.

    Go to the VM instances page

  • To view the logs generated by your Compute Engine resources, in the GCP Console, go to the Logs page.

    Go to the Logs page

    Logging is automatically configured to gather logs from various common services, including syslog.

Horizontal scaling with multiple instances

Multiple-instance deployment with managed instances

Compute Engine can scale horizontally. By using a managed instance group and the Compute Engine autoscaler, Compute Engine can automatically create instances of your app when needed and shut down instances when demand is low. You can set up an HTTP load balancer to distribute traffic to the instances in a managed instance group.

Deployment script

The sample app includes a script that automates the following deployment steps. The script named deploy.sh deploys the resources for a complete, autoscaled, load-balanced app as described in Horizontal scaling with multiple instances.

You can run each of the following steps yourself, or run gce/deploy.sh from the gce directory.

Create a managed instance group

A managed instance group is a group of homogeneous instances based on the same instance template. An instance template defines the configuration of your instance, including source image, disk size, scopes, and metadata (including startup scripts).

  1. Create a template.

    gcloud compute instance-templates create my-app-tmpl \
        --machine-type=g1-small \
        --scopes logging-write,storage-ro,https://www.googleapis.com/auth/projecthosting \
        --metadata-from-file startup-script=gce_deployment/startup-script.sh,project-config=config/settings.yml \
        --image ubuntu-15-04 \
        --tags http-server
    
  2. Create an instance group.

    gcloud compute instance-groups managed create my-app-group \
        --base-instance-name my-app \
        --size 2 \
        --template my-app-tmpl \
        --zone us-central1-f
    

    The --size parameter specifies the number of instances in the group. When all of the instances finish running their startup scripts, you can access the instances individually by using their external IP addresses and port 8080. To find the external IP addresses of the instances, enter gcloud compute instances list. The managed instances have names that start with the same prefix, my-app, which you specified in the --base-instance-name parameter.

Create a load balancer

An individual instance is fine for testing or debugging, but for serving web traffic it's better to use a load balancer to automatically direct traffic to available instances.

  1. Create a health check.

    The load balancer uses a health check to determine which instances are capable of serving traffic.

    gcloud compute http-health-checks create ah-health-check \
        --request-path /_ah/health
    
  2. Create a named port.

    The HTTP load balancer looks for the http service to know which port to direct traffic to. In your existing instance group, give port 8080 the name http.

    gcloud compute instance-groups managed set-named-ports my-app-group \
        --named-ports http:8080 \
        --zone us-central1-f
    
  3. Create a backend service.

    The backend service is the target for load-balanced traffic. It defines which instance group the traffic is directed to and which health check to use.

    gcloud compute backend-services create my-app-service \
        --http-health-check ah-health-check
    
  4. Add the backend service.

    gcloud compute backend-services add-backend my-app-service \
        --group my-app-group \
        --zone us-central1-f
    
  5. Create a URL map and proxy.

    The URL map defines which URLs are directed to which backend services. In this sample, all traffic is served by one backend service. If you want to load balance requests between multiple regions or groups, you can create multiple backend services. A proxy receives traffic and forwards it to backend services by using URL maps.

    1. Create the URL map.

      gcloud compute url-maps create my-app-service-map \
          --default-service my-app-service
      
    2. Create the proxy.

      gcloud compute target-http-proxies create my-app-service-proxy \
          --url-map my-app-service-map
      
  6. Create a global forwarding rule. The global forwarding rule ties a public IP address and port to a proxy.

    gcloud compute forwarding-rules create my-app-service-http-rule \
        --global \
        --target-http-proxy my-app-service-proxy \
        --port-range 80
    

Configure the autoscaler

The load balancer ensures that traffic is distributed across all of your healthy instances. But what happens if there is too much traffic for your instances to handle? You could manually add more instances. But a better solution is to configure a Compute Engine autoscaler to automatically create and delete instances in response to traffic demands.

  1. Create an autoscaler.

    gcloud compute instance-groups managed set-autoscaling my-app-group \
        --max-num-replicas 10 \
        --target-load-balancing-utilization 0.5 \
        --zone us-central1-f
    

    The preceding command creates an autoscaler on the managed instance group that automatically scales up to 10 instances. Instances are added when the load balancer is above 50% utilization and are removed when utilization falls below 50%.

  2. Create a firewall rule.

    Linux/macOS

    gcloud compute firewall-rules create default-allow-http-8080 \
        --allow tcp:8080 \
        --source-ranges 0.0.0.0/0 \
        --target-tags http-server \
        --description "Allow port 8080 access to http-server"
    

    Windows

    gcloud compute firewall-rules create default-allow-http-8080 ^
        --allow tcp:8080 ^
        --source-ranges 0.0.0.0/0 ^
        --target-tags http-server ^
        --description "Allow port 8080 access to http-server"
    

  3. Check progress until at least one of your instances reports HEALTHY.

    gcloud compute backend-services get-health frontend-web-service --global
    

View your app

  1. Get the forwarding IP address for the load balancer.

    gcloud compute forwarding-rules list --global
    

    Your forwarding-rules IP address is in the IP_ADDRESS column.

  2. In a browser, enter the IP address from the list.

    Your load-balanced and autoscaled app is now running on Compute Engine.

Manage and monitor your deployment

To manage and monitor your deployment, use the GCP Console.

  • To manage and monitor your load balancing configuration (including URL maps and backend services), in the GCP Console, go to the Load balancing page.

    Go to the Load balancing page

  • To manage and monitor your managed instance group and autoscaling configuration, in the GCP Console, go to the Instance groups page.

    Go to the Instance groups page

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Run the teardown script

If you ran the deploy.sh script, run the teardown.sh script to remove all resources created by the deploy.sh script. This returns your project to its state before running the deploy.sh script and helps to avoid further billing. To remove the single instance and the storage bucket created at the beginning of the tutorial, follow the instructions in the next section.

Delete resources manually

If you followed the steps in this tutorial manually, you can manually delete the cloud resources that you created.

Delete your load balancer

  1. In the GCP Console, go to the Load Balancing page.

    Go to the Load Balancing page

  2. Select the checkbox next to the load balancer that you want to delete, and then click Deletedelete.

  3. In the Delete load balancer dialog, select the associated backend service and health check resources, and then click Deletedelete. The load balancer and its associated resources are deleted.

Delete your Compute Engine managed instance group

  1. GCP Console で、[インスタンス グループ] ページに移動します。

    [インスタンス グループ] ページに移動

  2. 次のチェックボックスをオンにします。 削除するインスタンス グループ。
  3. インスタンス グループを削除するには、ページの上部にある [削除]()をクリックします。

Delete your single Compute Engine instance

  1. GCP Console の [VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. 次のチェックボックスをオンにします。 削除するインスタンス。
  3. インスタンスを削除するには、[削除] () をクリックします。

Delete your Cloud Storage bucket

  1. GCP Console で、Cloud Storage ブラウザページに移動します。

    Cloud Storage ブラウザページに移動

  2. 削除したいバケットの隣にあるチェックボックスをクリックします。
  3. ページの上部にある [削除] をクリックし、バケットを削除します。

What's next

このページは役立ちましたか?評価をお願いいたします。