|
| 1 | +## Run Symfony on App Engine Standard for PHP 7.2 |
| 2 | + |
| 3 | +This tutorial will walk you through how to create and deploy a Symfony project |
| 4 | +to App Engine Standard for PHP 7.2. You will learn how to: |
| 5 | + |
| 6 | +1. Create a [Symfony][symfony] project |
| 7 | +1. Configure it to run in the App Engine environment |
| 8 | +1. Deploy it to App Engine |
| 9 | +1. Set up a [Cloud SQL][cloud-sql] database |
| 10 | +1. Configure Doctrine to communicate with Cloud SQL |
| 11 | + |
| 12 | +> **Note**: This repository is just a tutorial and is not a Symfony project in |
| 13 | + and of itself. The steps will require you to set up a new Symfony project in a |
| 14 | + separate directory. |
| 15 | + |
| 16 | +## Prerequisites |
| 17 | + |
| 18 | +1. [Create a project][create-project] in the Google Cloud Platform Console |
| 19 | + and make note of your project ID. |
| 20 | +1. [Enable billing][enable-billing] for your project. |
| 21 | +1. Install the [Google Cloud SDK](https://cloud.google.com/sdk/). |
| 22 | + |
| 23 | +## Install |
| 24 | + |
| 25 | +This tutorial uses the [Symfony Demo][symfony-demo] application. Run the |
| 26 | +following command to install it: |
| 27 | + |
| 28 | +```sh |
| 29 | +PROJECT_DIR='symfony-on-appengine' |
| 30 | +composer create-project symfony/symfony-demo:^1.2 $PROJECT_DIR |
| 31 | +``` |
| 32 | + |
| 33 | +## Run |
| 34 | + |
| 35 | +1. Run the app with the following command: |
| 36 | + |
| 37 | + php bin/console server:run |
| 38 | + |
| 39 | +1. Visit [http://localhost:8000](http://localhost:8000) to see the Symfony |
| 40 | + Welcome page. |
| 41 | + |
| 42 | +## Deploy |
| 43 | + |
| 44 | +1. Remove the `scripts` section from `composer.json` in the root of your |
| 45 | + project. You can do this manually, or by running the following line of code |
| 46 | + below in the root of your Symfony project: |
| 47 | + |
| 48 | + ```sh |
| 49 | + php -r "file_put_contents('composer.json', json_encode(array_diff_key(json_decode(file_get_contents('composer.json'), true), ['scripts' => 1]), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));" |
| 50 | + ``` |
| 51 | + |
| 52 | + > **Note**: The composer scripts run on the [Cloud Build][cloud-build] server. |
| 53 | + This is a temporary fix to prevent errors prior to deployment. |
| 54 | + |
| 55 | +1. Copy the [`app.yaml`](app.yaml) file from this repository into the root of |
| 56 | + your project and replace `YOUR_APP_SECRET` with a new secret or the generated |
| 57 | + secret in `.env`: |
| 58 | + |
| 59 | + ```yaml |
| 60 | + runtime: php72 |
| 61 | + |
| 62 | + env_variables: |
| 63 | + APP_ENV: prod |
| 64 | + APP_SECRET: YOUR_APP_SECRET |
| 65 | + |
| 66 | + # URL handlers |
| 67 | + # ... |
| 68 | + ``` |
| 69 | + |
| 70 | + > **NOTE** Read more about the [env][symfony-env] and [secret][symfony-secret] |
| 71 | + parameters in Symfony's documentation. |
| 72 | + |
| 73 | +1. [Override the cache and log directories][symfony-override-cache] so that |
| 74 | + they use `/tmp` in production. This is done by modifying the functions |
| 75 | + `getCacheDir` and `getLogDir` to the following in `src/Kernel.php`: |
| 76 | + |
| 77 | + |
| 78 | + ```php |
| 79 | + class Kernel extends BaseKernel |
| 80 | + { |
| 81 | + //... |
| 82 | +
|
| 83 | + public function getCacheDir() |
| 84 | + { |
| 85 | + if ($this->environment === 'prod') { |
| 86 | + return sys_get_temp_dir(); |
| 87 | + } |
| 88 | + return $this->getProjectDir() . '/var/cache/' . $this->environment; |
| 89 | + } |
| 90 | +
|
| 91 | + public function getLogDir() |
| 92 | + { |
| 93 | + if ($this->environment === 'prod') { |
| 94 | + return sys_get_temp_dir(); |
| 95 | + } |
| 96 | + return $this->getProjectDir() . '/var/log'; |
| 97 | + } |
| 98 | +
|
| 99 | + // ... |
| 100 | + } |
| 101 | + ``` |
| 102 | + |
| 103 | + > **NOTE**: This is required because App Engine's file system is **read-only**. |
| 104 | + |
| 105 | +1. Deploy your application to App Engine: |
| 106 | + |
| 107 | + gcloud app deploy |
| 108 | + |
| 109 | +1. Visit `http://YOUR_PROJECT_ID.appspot.com` to see the Symfony demo landing |
| 110 | + page. |
| 111 | + |
| 112 | +The homepage will load when you view your application, but browsing to any of |
| 113 | +the other demo pages will result in a **500** error. This is because you haven't |
| 114 | +set up a database yet. Let's do that now! |
| 115 | + |
| 116 | +## Connect to Cloud SQL with Doctrine |
| 117 | + |
| 118 | +Next, connect your Symfony demo application with a [Cloud SQL][cloud-sql] |
| 119 | +database. This tutorial uses the database name `symfonydb` and the username |
| 120 | +`root`, but you can use whatever you like. |
| 121 | + |
| 122 | +### Setup |
| 123 | + |
| 124 | +1. Follow the instructions to set up a |
| 125 | + [Google Cloud SQL Second Generation instance for MySQL][cloud-sql-create]. |
| 126 | + |
| 127 | +1. Create a database for your Symfony application. Replace `INSTANCE_NAME` |
| 128 | + with the name of your instance: |
| 129 | + |
| 130 | + gcloud sql databases create symfonydb --instance=INSTANCE_NAME |
| 131 | + |
| 132 | +1. Enable the [Cloud SQL APIs][cloud-sql-apis] in your project. |
| 133 | + |
| 134 | +1. Follow the instructions to |
| 135 | + [install and run the Cloud SQL proxy client on your local machine][cloud-sql-install]. |
| 136 | + The Cloud SQL proxy is used to connect to your Cloud SQL instance when |
| 137 | + running locally. This is so you can run database migrations locally to set up |
| 138 | + your production database. |
| 139 | + |
| 140 | + * Use the [Cloud SDK][cloud-sdk] from the command line to run the following |
| 141 | + command. Copy the `connectionName` value for the next step. Replace |
| 142 | + `INSTANCE_NAME` with the name of your instance: |
| 143 | + |
| 144 | + gcloud sql instances describe INSTANCE_NAME |
| 145 | + |
| 146 | + * Start the Cloud SQL proxy and replace `INSTANCE_CONNECTION_NAME` with |
| 147 | + the connection name you retrieved in the previous step: |
| 148 | + |
| 149 | + cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 & |
| 150 | + |
| 151 | + **Note:** Include the `-credential_file` option when using the proxy, or |
| 152 | + authenticate with `gcloud`, to ensure proper authentication. |
| 153 | + |
| 154 | +### Configure |
| 155 | + |
| 156 | +1. Modify your Doctrine configuration in `config/packages/doctrine.yml` and |
| 157 | + change the parameters under `doctrine.dbal` to be the following: |
| 158 | + |
| 159 | + ```yaml |
| 160 | + # Doctrine Configuration |
| 161 | + doctrine: |
| 162 | + dbal: |
| 163 | + driver: pdo_mysql |
| 164 | + url: '%env(resolve:DATABASE_URL)%' |
| 165 | +
|
| 166 | + # ORM configuration |
| 167 | + # ... |
| 168 | + ``` |
| 169 | + |
| 170 | +1. Use the Symfony CLI to connect to your instance and create a database for |
| 171 | + the application. Be sure to replace `DB_PASSWORD` with the root password you |
| 172 | + configured: |
| 173 | + |
| 174 | + # create the database using doctrine |
| 175 | + DATABASE_URL="mysql://root:[email protected]:3306/symfonydb" \ |
| 176 | + bin/console doctrine:schema:create |
| 177 | + |
| 178 | +1. Modify your `app.yaml` file with the following contents. Be sure to replace |
| 179 | + `DB_PASSWORD` and `INSTANCE_CONNECTION_NAME` with the values you created for |
| 180 | + your Cloud SQL instance: |
| 181 | + |
| 182 | + ```yaml |
| 183 | + runtime: php72 |
| 184 | +
|
| 185 | + env_variables: |
| 186 | + APP_ENV: prod |
| 187 | + APP_SECRET: YOUR_APP_SECRET |
| 188 | +
|
| 189 | + # Add the DATABASE_URL environment variable |
| 190 | + DATABASE_URL: mysql://root:DB_PASSWORD@localhost?unix_socket=/cloudsql/INSTANCE_CONNECTION_NAME;dbname=symfonydb |
| 191 | +
|
| 192 | + # URL handlers |
| 193 | + # ... |
| 194 | + ``` |
| 195 | + |
| 196 | +### Run |
| 197 | + |
| 198 | +1. Now you can run locally and verify the connection works as expected. |
| 199 | + |
| 200 | + DB_HOST="127.0.0.1" DB_DATABASE=symfony DB_USERNAME=root DB_PASSWORD=YOUR_DB_PASSWORD \ |
| 201 | + php bin/console server:run |
| 202 | + |
| 203 | +1. Reward all your hard work by running the following command and deploying |
| 204 | + your application to App Engine: |
| 205 | + |
| 206 | + gcloud app deploy |
| 207 | + |
| 208 | +### What's Next |
| 209 | + |
| 210 | +1. Check out the [Databases and the Doctrine ORM][symfony-doctrine] documentation for Symfony. |
| 211 | +1. View a [Symfony Demo Application][symfony-sample-app] for App Engine Flex. |
| 212 | + |
| 213 | +[php-gcp]: https://cloud.google.com/php |
| 214 | +[cloud-sdk]: https://cloud.google.com/sdk/ |
| 215 | +[cloud-build]: https://cloud.google.com/cloud-build/ |
| 216 | +[cloud-sql]: https://cloud.google.com/sql/docs/ |
| 217 | +[cloud-sql-create]: https://cloud.google.com/sql/docs/mysql/create-instance |
| 218 | +[cloud-sql-install]: https://cloud.google.com/sql/docs/mysql/connect-external-app#install |
| 219 | +[cloud-sql-apis]:https://pantheon.corp.google.com/apis/library/sqladmin.googleapis.com/?pro |
| 220 | +[create-project]: https://cloud.google.com/resource-manager/docs/creating-managing-projects |
| 221 | +[enable-billing]: https://support.google.com/cloud/answer/6293499?hl=en |
| 222 | +[php-gcp]: https://cloud.google.com/php |
| 223 | +[symfony]: http://symfony.com |
| 224 | +[symfony-install]: http://symfony.com/doc/current/setup.html |
| 225 | +[symfony-welcome]: https://symfony.com/doc/current/_images/welcome.png |
| 226 | +[composer-json]: https://storage.googleapis.com/gcp-community/tutorials/run-symfony-on-appengine-flexible/composer-json.png |
| 227 | +[symfony-doctrine]: https://symfony.com/doc/current/doctrine.html |
| 228 | +[symfony-sample-app]: https://github.com/bshaffer/symfony-on-app-engine-flex |
| 229 | +[symfony-demo]: https://github.com/symfony/demo |
| 230 | +[symfony-secret]: http://symfony.com/doc/current/reference/configuration/framework.html#secret |
| 231 | +[symfony-env]: https://symfony.com/doc/current/configuration/environments.html#executing-an-application-in-different-environments |
| 232 | +[symfony-override-cache]: https://symfony.com/doc/current/configuration/override_dir_structure.html#override-the-cache-directory |
0 commit comments