# GCP: App Engine

In this step-by-step guide, we'll guide you how to deploy your VulcanSQL project to Google Cloud Platform(GCP)
using [App Engine](https://cloud.google.com/appengine). It's an application platform for developers to build monolithic
server-side rendered websites.

:::info
For more detailed information of the deployment process, you can [read more here](https://cloud.google.com/appengine/docs/standard/nodejs/runtime).
:::

## Step 1: Install and setup the Google Cloud CLI

Before you begin to use Cloud Run on GCP, you need to do several things:
1. In the Google Cloud console, on the [project selector page](https://console.cloud.google.com/projectselector2/home/dashboard), select or create a Google Cloud project.
2. [Make sure the billing is enabled for your Google Cloud project.](https://cloud.google.com/billing/docs/how-to/verify-billing-enabled#console)
3. [Install](https://cloud.google.com/sdk/docs/install) the Google Cloud CLI.
4. Initialize the gcloud CLI with the following command:
    ```shell
    gcloud init
    ```
5. You can set the default project for your Cloud Run service with the following command:
    ```shell
    gcloud config set project [PROJECT_ID]
    ```

For more detailed instructions on how to setup the environment, you can [read more here](https://cloud.google.com/appengine/docs/standard/nodejs/building-app/creating-project).

## Step 2: Package your VulcanSQL API Server

In this guide, we'll deploy your VulcanSQL API Server without Docker. So please execute the following command in the terminal:

```bash
vulcan package --output node
```

After executing the command, you'll see a message shown like below and a new directory `dist` in the project directory.

```bash
2023-08-08 08:59:27.666  INFO  [CORE] Package successfully, you can go to "dist" folder and run "npm install && node index.js" to start the server 
✔ Package successfully.
```

The directory structure of `dist` is as following:

```
dist
├── config.json
├── index.js
├── package.json
└── result.json
```

:::caution
External resources and configurations, such as `profiles.yaml`, are not copied to the `dist` folder. 
You'll need to copy them manually. We strongly recommend using a separate profile instead of the one used for development.
:::

## Step 3: Deploy to App Engine from source

Now we need to do several things before deploying the app to App Engine:

**1. Add `port:8080` to `config.json`**

Since App Engine accepts network traffic with the [port 8080](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/build#listening_to_port_8080).

**2. Change the filename of `index.js` to `server.js` and also in `package.json`**

Since App Engine recognizes [`server.js`](https://cloud.google.com/appengine/docs/standard/nodejs/building-app/writing-web-service#running_the_server_locally) as the entry file.

**3. Create a new file `app.yaml` and fill in the following content**

```yaml
runtime: nodejs
env: flex
runtime_config:
    operating_system: "ubuntu22"
    runtime_version: "18"
```

Finally, you can run the following command to deploy your app in the terminal:

```shell
gcloud app deploy
```

After successfully deploying your VulcanSQL app, you'll see the similar message in the terminal:

```
Deployed service [default] to [https://cannerflow-286003.uw.r.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse
```

Congratulations! Now your VulcanSQL app is on the cloud and is ready to be shared to the world!

:::info
If you need to clean up the resources on App Engine, you can [read the documentation here](https://cloud.google.com/appengine/docs/standard/python3/building-app/cleaning-up).
:::

## Step 4: (Optional) Deploy your VulcanSQL API Catalog Server

If you need to deploy API Catalog Server, you should execute the following command in the terminal:

```shell
vulcan package -t catalog-server
```

:::caution
The folder generated by the command is also called `dist`, so if you had executed the command of packaging
API server, you should rename the `dist` folder generated previously to prevent from being overwritten.
:::

Now we need to do several things before deploying the app to App Engine:

**1. Add `"config": {"port": 8080}` to `config.json`**

Since App Engine accepts network traffic with the [port 8080](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/build#listening_to_port_8080).

**2. Change the filename of `index.js` to `server.js` and also in `package.json`**

Since App Engine recognizes [`server.js`](https://cloud.google.com/appengine/docs/standard/nodejs/building-app/writing-web-service#running_the_server_locally) as the entry file.

**3. Create a new file `app.yaml` and fill in the following content**

```yaml
runtime: nodejs
env: flex
runtime_config:
    operating_system: "ubuntu22"
    runtime_version: "18"
env_variables:
    VULCAN_SQL_HOST: [Your VulcanSQL API Server URL]
```

Finally, you execute the same Google Cloud CLI commands used in the step 3 in the terminal:

```
gcloud app deploy
```
