Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions run/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>

# Google Cloud Run PHP Samples

[Cloud Run][run_docs] runs stateless [containers](https://cloud.google.com/containers/) on a fully managed environment or in your own GKE cluster.

## Samples

| Sample | Description | Deploy |
| --------------------------------------- | ------------------------ | ------------- |
|[Hello World][helloworld] | Quickstart | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_helloworld] |

For more Cloud Run samples beyond PHP, see the main list in the [Cloud Run Samples repository](https://github.com/GoogleCloudPlatform/cloud-run-samples).

## Setup

1. [Set up for Cloud Run development](https://cloud.google.com/run/docs/setup)

2. Clone this repository:

```sh
git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git
```

## How to run a sample locally

1. [Install docker locally](https://docs.docker.com/install/)

2. [Build the sample container](https://cloud.google.com/run/docs/building/containers#building_locally_and_pushing_using_docker):

```sh
export SAMPLE='helloworld'
cd php-docs-samples/run/$SAMPLE
docker build --tag $SAMPLE .
```

3. [Run containers locally](https://cloud.google.com/run/docs/testing/local)

With the built container:

```sh
PORT=8080 && docker run --rm -p 8080:${PORT} -e PORT=${PORT} $SAMPLE
```

Overriding the built container with local code:

```sh
PORT=8080 && docker run --rm \
-p 8080:${PORT} -e PORT=${PORT} \
-v $PWD:/usr/src/app $SAMPLE
```

Injecting your service account key:

```sh
export SA_KEY_NAME=my-key-name-123
PORT=8080 && docker run --rm \
-p 8080:${PORT} -e PORT=${PORT} \
-e GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/${SA_KEY_NAME}.json \
-v $GOOGLE_APPLICATION_CREDENTIALS:/tmp/keys/${SA_KEY_NAME}.json:ro \
-v $PWD:/usr/src/app $SAMPLE
```

Opening a shell in the container:

1. Build the container.

2. Run the container with a shell:

```sh
PORT=8080 && docker run --rm \
--interactive --tty \
-p 8080:${PORT} -e PORT=${PORT} \
-v $PWD:/var/www/html $SAMPLE \
/bin/bash
```

3. Exit the container: `Ctrl-D`

## Deploying

See [Building containers][run_build] and [Deploying container images][run_deploy]
for more information.

[run_docs]: https://cloud.google.com/run/docs/
[run_build]: https://cloud.google.com/run/docs/building/containers
[run_deploy]: https://cloud.google.com/run/docs/deploying
[helloworld]: helloworld/
[run_button_helloworld]: https://deploy.cloud.run/?dir=run/helloworld
13 changes: 13 additions & 0 deletions run/helloworld/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The .dockerignore file excludes files from the container build process.
#
# https://docs.docker.com/engine/reference/builder/#dockerignore-file

# Exclude locally vendored dependencies.
vendor/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore
12 changes: 12 additions & 0 deletions run/helloworld/.gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# The .gcloudignore file excludes file from upload to Cloud Build.
# If this file is deleted, gcloud will default to .gitignore.
#
# https://cloud.google.com/cloud-build/docs/speeding-up-builds#gcloudignore
# https://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore

# Exclude locally vendored dependencies.
vendor/

# Exclude git history and configuration.
.git/
.gitignore
53 changes: 53 additions & 0 deletions run/helloworld/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START run_helloworld_dockerfile]

# Use the official PHP image.
# https://hub.docker.com/_/php
FROM php:7.4-apache

# Configure PHP for Cloud Run.
# Precompile PHP code with opcache.
RUN docker-php-ext-install -j "$(nproc)" opcache
RUN set -ex; \
{ \
echo "; Cloud Run enforces memory & timeouts"; \
echo "memory_limit = -1"; \
echo "max_execution_time = 0"; \
echo "; File upload at Cloud Run network limit"; \
echo "upload_max_filesize = 32M"; \
echo "post_max_size = 32M"; \
echo "; Configure Opcache for Containers"; \
echo "opcache.enable = On"; \
echo "opcache.validate_timestamps = Off"; \
echo "; Configure Opcache Memory (Application-specific)"; \
echo "opcache.memory_consumption = 32"; \
} > "$PHP_INI_DIR/conf.d/cloud-run.ini"

# Copy in custom code from the host machine.
WORKDIR /var/www/html
COPY . ./

# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

# Configure PHP for development.
# Switch to the production php.ini for production operations.
# RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# https://github.com/docker-library/docs/blob/master/php/README.md#configuration
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

# [END run_helloworld_dockerfile]
5 changes: 5 additions & 0 deletions run/helloworld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Hello World for Cloud Run

This sample demonstrates how to deploy a **Hello World** application to Cloud Run.

**View the [full tutorial](https://cloud.google.com/run/docs/quickstarts/build-and-deploy#php)**
23 changes: 23 additions & 0 deletions run/helloworld/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Copyright 2020 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// [START run_helloworld_service]

$name = getenv('NAME', true) ?: 'World';
echo sprintf('Hello %s!', $name);

// [END run_helloworld_service]
23 changes: 23 additions & 0 deletions run/helloworld/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2020 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<phpunit bootstrap="../../testing/vendor/autoload.php" convertWarningsToExceptions="false">
<testsuites>
<testsuite name="Cloud Run Hello World tests">
<directory>test</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>
119 changes: 119 additions & 0 deletions run/helloworld/test/DeployTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
/**
* Copyright 2020 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Google\Cloud\Samples\Run\Helloworld;

use Google\Auth\ApplicationDefaultCredentials;
use Google\Cloud\TestUtils\DeploymentTrait;
use Google\Cloud\TestUtils\EventuallyConsistentTestTrait;
use Google\Cloud\TestUtils\GcloudWrapper\CloudRun;
use Google\Cloud\TestUtils\TestTrait;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use PHPUnit\Framework\TestCase;

/**
* Class DeployTest.
*/
class DeloyTest extends TestCase
{
use DeploymentTrait;
use EventuallyConsistentTestTrait;
use TestTrait;

/** @var \Google\Cloud\TestUtils\GcloudWrapper\CloudRun */
private static $service;

/** @var string */
private static $image;

/**
* Deploy the application.
*
* @beforeClass
*/
public static function setUpDeploymentVars()
{
$projectId = self::requireEnv('GOOGLE_PROJECT_ID');
$versionId = self::requireEnv('GOOGLE_VERSION_ID');
self::$service = new CloudRun($projectId, ['service' => $versionId]);
self::$image = sprintf('gcr.io/%s/%s:latest', $projectId, $versionId);
}

private static function beforeDeploy()
{
// Ensure setUpDeploymentVars has been called
if (is_null(self::$service)) {
self::setUpDeploymentVars();
}

// Suppress gcloud prompts during deployment.
putenv('CLOUDSDK_CORE_DISABLE_PROMPTS=1');
}

/**
* Deploy the Cloud Run service.
*/
private static function doDeploy()
{
if (false === self::$service->build(self::$image)) {
return false;
}

if (false === self::$service->deploy(self::$image)) {
return false;
}

return true;
}

/**
* Delete a deployed Cloud Run service.
*/
private static function doDelete()
{
self::$service->delete();
self::$service->deleteImage(self::$image);
}

public function testService()
{
$targetAudience = self::getBaseUri();

// create middleware
$middleware = ApplicationDefaultCredentials::getIdTokenMiddleware($targetAudience);
$stack = HandlerStack::create();
$stack->push($middleware);

// create the HTTP client
$client = new Client([
'handler' => $stack,
'auth' => 'google_auth',
'base_uri' => $targetAudience,
]);

// Run the test.
$resp = $client->get('/');
$this->assertEquals('200', $resp->getStatusCode());
$this->assertEquals('Hello World!', (string) $resp->getBody());
}

public function getBaseUri()
{
return self::$service->getBaseUrl();
}
}
3 changes: 2 additions & 1 deletion testing/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"phpunit/phpunit": "^7",
"bshaffer/phpunit-retry-annotations": "^0.1.0",
"guzzlehttp/guzzle": "^7.0",
"symfony/browser-kit": "^4.0"
"symfony/browser-kit": "^4.0",
"google/auth": "^1.12"
}
}