Ускорьте свое веб-приложение Flutter: простое развертывание в Google Cloud Run
4 января 2024 г.Как серверный разработчик, я часто тесно сотрудничаю со своей командой внешнего интерфейса, чтобы обеспечить беспрепятственное развертывание веб-приложений. Недавно наша команда фронтенда выявила серьезную проблему, которая замедляла наш рабочий процесс разработки.
Постановка задачи 🤔
Они отвечали за управление веб-приложением Flutter, работающим на виртуальной машине (ВМ) Google Cloud Platform (GCP). Хотя само приложение было впечатляющим, процесс развертывания оставлял желать лучшего.
Существующий рабочий процесс развертывания представлял собой многоэтапное испытание:
- Создайте веб-приложение Flutter.
- Загрузите приложение на виртуальную машину.
- Разархивируйте загруженный пакет.
- Извлеките содержимое в соответствующий каталог Apache.
- А иногда что-то шло не так, и развертывание затягивалось слишком долго. ол>
- Бесшовная интеграция с GitHub.
- Триггеры Cloud Build для автоматической сборки и развертывания.
- Dockerfile для определения среды и зависимостей.
- Автоматическое создание и развертывание контейнеров.
- Динамическое масштабирование на основе входящих запросов.
- Экономичное распределение ресурсов.
- Совместная работа членов команды в режиме реального времени.
- Автоматическое развертывание внесенных изменений.
- Модель ценообразования с оплатой по мере использования.
- За простой не взимается плата.
- Подробные журналы и показатели.
- Интеграция с инструментами мониторинга, такими как Stackdriver.
- Настройка Docker для вашего проекта
- Настройка файлов Apache и сервера для бесперебойной работы вашего приложения в облаке
- И в конце настройка запуска облака.
- ==Теперь добавьте файл конфигурации Apache, чтобы сделать порт динамическим, поскольку при запуске в облаке ожидается открытая конфигурация порта для приложения==
Первоначальная попытка развертывания образа Docker 🐳
Наш первоначальный подход заключался в реализации развертывания образа Docker на виртуальной машине с помощью действий GitHub. Хотя это казалось многообещающим, быстро стало очевидно, что оно сопряжено со своими сложностями и проблемами.
* 🤯 Процесс создания образов Docker иногда приводил к сбоям, заставляя нас ломать голову. * 🔒 SSH-подключения к виртуальной машине иногда неожиданно прерывались, что приводило к неприятным задержкам в процессе развертывания. * ⌛ Тайм-ауты стали обычным явлением, что еще больше усугубило проблемы с развертыванием.
Было ясно, что наша первоначальная попытка была далека от того бесшовного решения, к которому мы стремились.
Спаситель в облаке ☁️
В поисках более эффективного решения для развертывания и оптимизации совместной работы мы наткнулись на Cloud Run, который изменил правила игры на нашем пути развертывания.
Вот некоторые ключевые функции, которые мы использовали:
Автоматическое развертывание с GitHub 🚀
Контейнеризация стала проще 🐳
Автоматическое масштабирование для повышения эффективности ⚖️
Извлечение кода с GitHub 🔄
Экономичность 💰
Надежный мониторинг и журналирование 📊
Решение – реализация: :stuck_out_tongue_winking_eye:
Теперь давайте перейдем к реальному решению, которое сработало для нас, добавив все подходящие нам шаблоны, чтобы вы также могли использовать их или изменить в соответствии со своими потребностями.
На этом этапе решения мы пройдем
Шаг 1. Настройка Docker в репозитории
* ==Добавьте этот файл докера в существующий репозиторий==
# Stage 1: Build the application
FROM dart:stable AS build
# Install dependencies for Flutter
RUN apt-get update && apt-get install -y curl git unzip xz-utils zip libglu1-mesa
# Clone the Flutter repository
RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter
# Set the Flutter path
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"
# Checkout the specific version of Flutter
RUN flutter channel stable
RUN flutter upgrade
RUN git -C /usr/local/flutter checkout 1f6bdb6
#above after checkout is commit hash which indicates the version of flutter
#to learn more about flutter versioning, please visit https://flutter.dev/docs/development/tools/sdk/releases?tab=linux
# Verify Flutter installation
RUN flutter doctor
# Set working directory
WORKDIR /app
# Copy over your app
COPY pubspec.* /app/
RUN flutter pub get
COPY . /app
RUN flutter pub get --offline
RUN flutter clean
RUN flutter build web --release --no-tree-shake-icons
# Stage 2: Create the runtime environment with Apache
FROM httpd:alpine
# Install gettext for envsubst
RUN apk add --no-cache gettext
# Copy the built app to the Apache server directory
COPY --from=build /app/build/web/ /usr/local/apache2/htdocs/
# Expose port
EXPOSE 8080
# Copy the Apache configuration template and startup script
COPY httpd.conf.template /usr/local/apache2/conf/httpd.conf.template
# Add a shell script to start Apache with the right PORT
COPY start-apache.sh /usr/local/bin/start-apache.sh
RUN chmod +x /usr/local/bin/start-apache.sh
# Start Apache using the startup script
CMD ["start-apache.sh"]
* Вышеуказанный файл Docker является многоэтапным. * На первом этапе мы загружаем зависимость флаттера и генерируем сборку. * На втором этапе мы настраиваем Apache для размещения этого статического сайта в облаке
# this should go in directory with httpd.conf.template
ServerRoot "/usr/local/apache2"
Listen ${PORT}
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule proxy_html_module modules/mod_proxy_html.so
<IfModule unixd_module>
User daemon
Group daemon
</IfModule>
ServerAdmin you@example.com
<Directory />
AllowOverride none
Require all denied
</Directory>
<Directory "/usr/local/apache2/htdocs">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
<Files ".ht*">
Require all denied
</Files>
ErrorLog /proc/self/fd/2
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
CustomLog /proc/self/fd/1 common
</IfModule>
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
</IfModule>
<Directory "/usr/local/apache2/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule headers_module>
RequestHeader unset Proxy early
</IfModule>
<IfModule mime_module>
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule mime_magic_module>
MIMEMagicFile conf/magic
</IfModule>
Include conf/extra/proxy-html.conf
* ==Добавьте только что добавленный файл сервера с именем start-apache.sh, чтобы добавить скрипт для бесперебойной работы сервера==
#!/bin/sh
# Substitute environment variables in Apache configuration
envsubst < /usr/local/apache2/conf/httpd.conf.template > /usr/local/apache2/conf/httpd.conf
# For debugging: print the PORT variable and the resulting httpd.conf
echo "PORT: $PORT"
# cat /usr/local/apache2/conf/httpd.conf
# Start Apache in the foreground
exec httpd -DFOREGROUND
* В приведенном выше файле добавьте порт из env с помощью envsubst и замените фактическую конфигурацию Apache. * Теперь, после добавления всего этого, просто попробуйте запустить приложение локально для тестирования, используя команду ниже для проверки
Javascript
1 сборка докера -t my-flutter-app. -> Для строительства
2 docker run -d -p 8080:8080 -e PORT=8080 my-flutter-app ->gt; Для запуска после сборки
* Если все вышеперечисленное работает нормально, отправьте его на github.
Шаг 2. Настройка Cloud Run
* ==Начните с перехода в Google Cloud Console и создания нового проекта или выбора существующего.== * В Cloud Console активируйте API Cloud Run для своего проекта.
* ==Вы сможете увидеть, как здесь движется облако, как показано на изображении ниже.==
* ==Теперь создайте облачную службу запуска==
* ==Заполните данные и выберите вариант облачной сборки==
* ==Выберите репозиторий и ветку и настройте файл докера в опции==
* ==Теперь нажмите «Сохранить» и все.== * ==Теперь начнется сборка, и вы сможете увидеть ее в разделе облачной сборки.==
* В конце после успешной сборки вы можете проверить свое веб-приложение на внешнем IP-адресе, предоставленном облаком.
Путешествие :car:
В этом блоге описывается наш путь от сложного процесса развертывания к оптимизированному и эффективному решению с использованием Cloud Run. Благодаря таким функциям, как автоматическое развертывание, контейнеризация, автоматическое масштабирование и экономическая эффективность, Cloud Run стал жизненно важным инструментом в нашем арсенале разработчиков. Попрощайтесь с проблемами развертывания и воспользуйтесь Cloud Run для более удобной разработки. ☁️🚀
Оригинал