Однажды мне понадобилось разместить учебный проект на 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
-
Для каждого проекта:
Создайте отдельную Application с подходящим регионом и часовой зоной
-
На экране ресурсов (resources), выбирайте:
Для server app Application: “Java” и “Standard Environment”
Для client app Application: “Other”(и Python) и “Standard Environment”
Создайте SQL instance с помощью "Quickstart for Cloud SQL for MySQL" (ссылка)
(только раздел “Create an instance”!)
Внимание, внимание! Не смотря на то, что Гугл выделяет некоторую сумму денег (точнее, кредитов) на первое время, эти деньги улетают вмиг и причина лишь одна - SQL. Поэтому, если вы не планируете мощный трафик между бэком, фронтом и датабазой, после создания SQL в настройках (SQL-> -> Edit configuration) выбирайте:
Region: Single zone
Machine type: db-f1-micro
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
В вашем проекте Spring Boot создайте:
а. папку src/main/appengine
б. файл app.yaml в src/main/appengineВ 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
После размещения бэка проверьте его App Engine URL-адрес (формат: https://PROJECT_ID.REGION_ID.r.appspot.com) и поставьте его в проекте Angular как BASE_URL для отправки HTTP-запросов.
В корневом каталоге проекта 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, предоставляющее доступ ко всем источникам!
Проверьте URL-адрес App Engine, назначенный вашему client app(фронт)
Добавьте этот URL-адрес в свою конфигурацию CORS
Повторно разместите server app (бэк), выполнив команду из командной строки:
mvn clean package appengine:deploy
Вот и все!!! Теперь и фронт и бэк бегут на Google App Engine.
Запускайте url вашего client app (фронт) в браузере и вперед!
Надеюсь, вам пригодился этот гид.