Continuously Build, Test, and Deploy with Symfony on Google Cloud
Tags: webdev, php, devops, serverless
Published: 2019-04-16 21:24:17

---
title: Continuously Build, Test, and Deploy with Symfony on Google Cloud
published: true
description: We will learned Continuously Build, Test, and Deploy with Symfony on Google Cloud
tags: #webdev #php #devops #serverless
---


Hi buddies, I'm going to talk about Symfony build, test and deploy on Google Cloud. With this way, we will able to get full automation each process. We'll have less tolerance regarding any human mistake. In order to provide this, we're supposed to install **gcloud**. You could follow this document, it's piece of cake. After that, you should just run all of these commands.

```bash
gcloud init
gcloud components install app-engine-php
gcloud auth login
gcloud config set project [GC-PROJECT-ID]
```

From now on, our gcloud sdk is authenticated to our Google Cloud Project. You can also follow Google's documents, if you have any trouble.

Well, let's create a Symfony project with Composer. Run these commands to run a Symfony application.

```
composer create-project symfony/skeleton mertblog -vvv && cd mertblog
composer require dotenv annotations template log google/cloud -vvv
composer require web-server-bundle maker tests --dev -vvv
bin/console make:controller
```

The content of the controller is as following. I changed only route.

```php
<?php
  
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController
{
    /**
     * @Route("/", name="default")
     */
    public function index()
    {
        return $this->render('default/index.html.twig', [
            'controller_name' => 'DefaultController',
        ]);
    }
}
```

That's it! We've all libraries and files which we will need further. In order to deploy into Google Cloud App Engine, I create the **app.yaml** in root directory of the project.

```yaml
runtime: php
env: flex

env_variables:
  APP_ENV: 'prod'
  DOCUMENT_ROOT: '/app/public'
```

Shortly after, I run this command to deploy.

```bash
gcloud app deploy
```

This command automatically reads this file and takes the actions. It may take a little long time. Whereas, everything is fine and going well, don't worry about it.
Once it's finished, run this, you're going to see our Default Controller response on App Engine production.

```bash
gcloud app browse
```

![alt text](https://thepracticaldev.s3.amazonaws.com/i/ixrwhaod6swd07ap8rli.png "")

Perfect! From now on, I am able to create a GitHub repository to automation and push Symfony application into this repository. As you see, my repository is ready.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/nm8inzglomqckave06lp.png "")

Right now, we have to integrate with GitHub and Google Cloud Build. For this, you can go to this page.

https://github.com/marketplace/google-cloud-build

You'll encounter this and click the **Set up a plan** button and go ahead. It will demand to a repository to run. I've selected my repository which I've created a moment ago.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/2xpl62opfaozuvvbypw8.png "")

![alt text](https://thepracticaldev.s3.amazonaws.com/i/qoy4no370d2iyykzflsh.png "")

With this way, Google Cloud Build and GitHub will integrated run smoothly. Now, I create a **Dockerfile** and **Docker ignore file** to create a container in root directory of the project. I'll use this container for testing my application.

```yaml
FROM gcr.io/google-appengine/php
```

Here is **.dockerfile**.

```yaml
.gcloudignore
.git
.gitignore
vendor/
var/
Dockerfile
.dockerignore
```

No more, we don't get any manual process. To automate my processes, I create a **cloudbuild.yaml** file in root directory of the project. There are 3 sections in this file. First of all, Google Cloud Build is building our application and testing according to our configuration. If these steps are succeed, it deploys to **App Engine**.

```yaml
steps:
  # Build
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'build', '--build-arg', 'COMPOSER_FLAGS=--dev', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '.' ]
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'push', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA' ]

  # Test
  - name: 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA'
    args: [ 'bin/phpunit' ]
    dir: /app
    env:
      - 'APP_ENV=test'

  # Deploy
  - name: 'gcr.io/cloud-builders/gcloud'
    args: ['beta', 'app', 'deploy', '--quiet', '--image-url', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '--version', '$BRANCH_NAME', '--no-promote']
```

But without deploying, we need to do somethings. For example, let's create a test class. 

```bash
bin/console make:functional-test IndexControllerTest
```

Here you are.

```php
<?php

namespace App\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class IndexControllerTest extends WebTestCase
{
    public function testSomething()
    {
        $client = static::createClient();
        $crawler = $client->request('GET', '/');

        $this->assertSame(200, $client->getResponse()->getStatusCode());
        $this->assertContains('Hello Mertblog', $crawler->filter('h1')->text());
    }
}
```

Nice! We check out the HTTP status code and the title of the page. We cannot pass this test because, our title is not **Hello Mertblog**. I won't change, because I would like to see failed build. Well, we have to grant permissions to Google Cloud Build for App Engine. As you see, I've set these permissions to Google Cloud Build.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/ffx5gzrycko92d3t76mq.png "")

In addition to this, you had better, not forget to add new files which we've just added on Git. I've pushed to GitHub my new files and it will be automatically builded on Google Cloud. If you go to Google Cloud Build page, you'll see it is failed because of our test. The HTTP response code is 200 but the title page is not as I demanded. It couldn't pass. By the way, deploying didn't run. Because, in order to deploy, other steps should succeed.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/rqhxgg3qbxo2ugu9trck.png "")

We can look over the details.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/du32bjynvts04xuxn4bc.png "")

You can also check on GitHub.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/ncm7fu47453jr20b1kns.png "")

Let's fix somethings such as our title on the page. I changed the title as **Hello Mertblog** and I push my new codes GitHub. 

From now on, every step is perfect. In order they succeeded regarding cases.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/dqmjan3ho0sgeyvr0wem.png "")

Now, As long as you go to **App Engine** you see 2 versions to run. And **master** version is our main version which is deploying from Github by Google Cloud Build. We have to change traffic, If we need to see changing on our repository. You can stop old version and click **Split Traffic** button on this page. And give 100% traffic. Like this.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/mvi1ij4qm1duvx1q6xsb.png "")

Let's check our homepage.As you see, my last codes were deployed obviously, the title was changed.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/012c7d9qn6hlh9tvat4j.png "")

In addition to this, I am going to check on GitHub. I could see that there is no any errors or failures stuffs. Well done!

![alt text](https://thepracticaldev.s3.amazonaws.com/i/r9oqif594u2w6vjl082q.png "")

# To Sum Up

If we gather, there is a big benefit and opportunity to use Google Cloud Build, Google Cloud App Engine and Symfony together. All processes are able to be automatic with this way and we can be away from mistakes. As long as if you have any trouble or problem, don't hesitate to stay in touch.