Однажды мне понадобилось разместить учебный проект на Google App Engine. Зачем? Почему именно там? Можно обсудить позже. Сейчас речь о другом.

Да, в сети есть куча инфы на эту тему, включая гугловскую документацию, но она разрозненная, а годного четкого мануала, содержащего шаги для деплоя всех трех составляющих, не нашлось.
Так появился этот гид (проверено, по состоянию на май 2021-го мин нет работает)

п.с. Первоначально статья писалась мной на английском, так что заранее прошу прощения, если перевод вам покажется кривоватым.

Итак, вам понадобится:

  • Spring Boot server app with Java 11 (бэкенд), написан на Eclipse

  • Google Cloud SDK

  • Angular 11 client app (фронтeнд), написан на MS Visual Code

  • Angular CLI

  • Google Cloud account с включенным биллингом (enabled billing) 

    Перед тем как начать:

  • Залогиньтесь в Google Cloud App Engine console (ссылка)

  • Создайте 2 проекта: один для server app и один для client app

  • Для каждого проекта:

    1. Создайте отдельную Application с подходящим регионом и часовой зоной

    2. На экране ресурсов (resources), выбирайте:

      1. Для server app Application: “Java” и “Standard Environment” 

      2. Для client app Application: “Other”(и Python) и “Standard Environment”

  • Создайте SQL instance с помощью "Quickstart for Cloud SQL for MySQL"  (ссылка)
    (только раздел “Create an instance”!)

Внимание, внимание! Не смотря на то, что Гугл выделяет некоторую сумму денег (точнее, кредитов) на первое время, эти деньги улетают вмиг и причина лишь одна - SQL. Поэтому, если вы не планируете мощный трафик между бэком, фронтом и датабазой, после создания SQL в настройках (SQL->  -> Edit configuration) выбирайте:

  1. Region: Single zone

  2. Machine type: db-f1-micro

  3. Storage: HDD

Кроме этого, рекомендуется определить бюджет и настроить алерты, предупреждающие о выходе за его рамки (Как это сделать) Кстати, помните, Гугл не прекращает биллинг даже когда у бюджета есть рамки.

Как настроить соединение с Google Cloud SQL database

1. Из консоли Google App Engine, перейдите в рабочую директорию инстанса Google Cloud SQL ( Google Cloud SQL instance's project directory) и откройте Cloud Shell
а. Запустите команду

gcloud sql connect <your-user-name> --user=root

б. Введите пароль
в. Создайте базу данных

CREATE DATABASE <your-database-name>;

2. В файле application.properties вашего бэкенда (Spring Boot), вставьте новые instance-connection-name, database-name, username и password

spring.cloud.gcp.sql.instance-connection-name=<your-Google-Cloud-SQL-instance's-project-ID>:<region>:<your-user-name>  
spring.cloud.gcp.sql.database-name=<your-database-name>  
spring.datasource.username=root  
spring.datasource.password=<your-password>

3. В файле pom.xml вашего бэкенда (Spring Boot) добавьте Spring Boot Starter for Google Cloud SQL dependency

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
	<version>1.2.7.RELEASE</version>
</dependency>

Таааааатам!!! Первая часть закончена: Бэк ака server app подсоединен к базе данных Google Cloud SQL!

Напоминаю: Бэк и фронт(server app and client app) размещаются в РАЗНЫХ проектах, но на одном аккаунте Google App Engine.

Как разместить бэк (Spring Boot server app) на Google App Engine

  1. В вашем проекте Spring Boot создайте:
    а. папку src/main/appengine
    б. файл app.yaml в src/main/appengine

  2. В app.yaml запишите конфигурацию

runtime: java11
instance_class: F4

Обратите внимание: instance_class не является обязательным, но рекомендуется для апп на Spring Boot-е потому что они занимают много места! Дифолтное значение для instance_class это F1.

3. Добавьте Cloud SDK-based Maven App Engine Plugin в ваш файл pom.xml:

<plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>2.2.0</version>
            <configuration>
                <version>1</version>
	       <projectId><your-Google-Cloud-server-side-project-ID></projectId>
            </configuration>
</plugin>

Обратите внимание: Google App Engine Standard Environment обеспечивает Jetty Web Server, поэтому нам не нужны Jetty dependencies, а также мы должны исключить Tomcat из Spring Boot Starter Web dependency

4. Добавьте в pom.xml file:


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!-- Exclude the Tomcat dependency -->
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</exclusion>
	</exclusions>
</dependency>

Обратите внимание: Также хорошо иметь плагин Maven Jetty в вашем pom.xml, который пригодится при запуске приложения на сервере Jetty, поскольку он сканирует и настраивает любые изменения в ваших исходных кодах на Java

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>11.0.2</version>
</dependency>

5. Обновите проект Maven на Eclipse: щелкните правой кнопкой мыши на проекте, затем Maven> Update project.

6. В корневом каталоге проекта, содержащем командную строку файла pom.xml, выполните команду:

mvn clean package appengine:deploy

Напоминаю: Бэк и фронт(server app and client app) размещаются в РАЗНЫХ проектах, но на одном аккаунте Google App Engine

Как разместить фронт(Angular 11 client app) to Google App Engine

  1. После размещения бэка проверьте его App Engine URL-адрес (формат: https://PROJECT_ID.REGION_ID.r.appspot.com) и поставьте его в проекте Angular как BASE_URL для отправки HTTP-запросов.

  2. В корневом каталоге проекта Angular создайте файл app.yaml со следующими конфигурациями:

runtime: python27
api_version: 1
threadsafe: true
  
handlers:
- url: /(.+\.js)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.js)

- url: /(.+\.css)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.css)

- url: /(.+\.png)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.png)

- url: /(.+\.jpg)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.jpg)

- url: /(.+\.svg)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.svg)

- url: /favicon.ico
  static_files: dist/your-project-name/favicon.ico
  upload: dist/your-project-name/favicon.ico

- url: /(.+\.json)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.json)

- url: /(.+)
  static_files: dist/your-project-name/index.html
  upload: dist/your-project-name/index.html

- url: /
  static_files: dist/your-project-name/index.html
  upload: dist/your-project-name/index.html

- url: /(.+\.otf)
  static_files: dist/your-project-name/\1
  upload: dist/your-project-name/(.+\.otf)

skip_files:
  - e2e/
  - node_modules/
  - src/
  - coverage
  - ^(.*/)?\..*$
  - ^(.*/)?.*\.json$
  - ^(.*/)?.*\.md$
  - ^(.*/)?.*\.yaml$
  - ^LICENSE

3. Чтобы скомпилировать приложение, в Angular CLI из вашего проекта запустите команду:

ng build --prod command 

4. Для размещения проекта на GCP, перейдите в папку, содержащую файл app.yaml, и запустите команду:

gcloud app deploy --project=<your-Google-Cloud-client-side-project-ID>

Обратите внимание: Если вам нужно указать конкретный URL-адрес в заголовке вашего server app (бэк) Access-Control-Allow-Origin, а не значение wildcard, предоставляющее доступ ко всем источникам!

  1. Проверьте URL-адрес App Engine, назначенный вашему client app(фронт)

  2. Добавьте этот URL-адрес в свою конфигурацию CORS

  3. Повторно разместите server app (бэк), выполнив команду из командной строки:

mvn clean package appengine:deploy

Вот и все!!! Теперь и фронт и бэк бегут на Google App Engine.
Запускайте url вашего client app (фронт) в браузере и вперед!

Надеюсь, вам пригодился этот гид.

Комментарии (0)