Skip to content

Commit f70e9cf

Browse files
authored
Add Symfony sample for PHP 7.2 on App Engine Standard (GoogleCloudPlatform#682)
1 parent 3e3dbd6 commit f70e9cf

File tree

10 files changed

+1535
-3
lines changed

10 files changed

+1535
-3
lines changed

.kokoro/secrets-example.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,9 @@ export LARAVEL_CLOUDSQL_CONNECTION_NAME=$CLOUDSQL_CONNECTION_NAME_MYSQL
112112
export LARAVEL_DB_DATABASE=laravel
113113
export LARAVEL_DB_USERNAME=$CLOUDSQL_USER
114114
export LARAVEL_DB_PASSWORD=$CLOUDSQL_PASSWORD
115+
116+
# Symfony
117+
export SYMFONY_CLOUDSQL_CONNECTION_NAME=$CLOUDSQL_CONNECTION_NAME_MYSQL
118+
export SYMFONY_DB_DATABASE=symfony
119+
export SYMFONY_DB_USERNAME=$CLOUDSQL_USER
120+
export SYMFONY_DB_PASSWORD=$CLOUDSQL_PASSWORD
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
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
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
runtime: php72
2+
3+
env_variables:
4+
APP_ENV: prod
5+
APP_SECRET: YOUR_APP_SECRET
6+
# APP_DEBUG: true
7+
8+
## For connecting to Cloud SQL with Doctrine
9+
## This is used in part two of the README:
10+
# DATABASE_URL: mysql://root:DB_PASSWORD@localhost?unix_socket=/cloudsql/INSTANCE_CONNECTION_NAME;dbname=symfonydb
11+
12+
handlers:
13+
# Declare the build and bundles directory as static assets to be served by the
14+
# App Engine CDN.
15+
- url: /build
16+
static_dir: public/build
17+
- url: /bundles
18+
static_dir: public/bundles
19+
20+
# Declare any media files in the public directory as static assets as well.
21+
- url: /(.*\.(ico|txt|gif|png|jpg))$
22+
static_files: public/\1
23+
upload: public/.*\.(ico|txt|gif|png|jpg)$
24+
25+
# Declare a catch-all to send all other routes to be handled by the application.
26+
- url: .*
27+
script: auto
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"require": {
3+
"php": "^7.1.3"
4+
},
5+
"require-dev": {
6+
"google/cloud-tools": "^0.8.2",
7+
"monolog/monolog": "^1.19",
8+
"nikic/php-parser": "^4.0"
9+
}
10+
}

0 commit comments

Comments
 (0)