Ускорьте свое веб-приложение Flutter: простое развертывание в Google Cloud Run

Ускорьте свое веб-приложение Flutter: простое развертывание в Google Cloud Run

4 января 2024 г.

Как серверный разработчик, я часто тесно сотрудничаю со своей командой внешнего интерфейса, чтобы обеспечить беспрепятственное развертывание веб-приложений. Недавно наша команда фронтенда выявила серьезную проблему, которая замедляла наш рабочий процесс разработки.

Постановка задачи 🤔

Они отвечали за управление веб-приложением Flutter, работающим на виртуальной машине (ВМ) Google Cloud Platform (GCP). Хотя само приложение было впечатляющим, процесс развертывания оставлял желать лучшего.

Существующий рабочий процесс развертывания представлял собой многоэтапное испытание:

  1. Создайте веб-приложение Flutter.
  2. Загрузите приложение на виртуальную машину.
  3. Разархивируйте загруженный пакет.
  4. Извлеките содержимое в соответствующий каталог Apache.
  5. А иногда что-то шло не так, и развертывание затягивалось слишком долго.
  6. Первоначальная попытка развертывания образа Docker 🐳

    Наш первоначальный подход заключался в реализации развертывания образа Docker на виртуальной машине с помощью действий GitHub. Хотя это казалось многообещающим, быстро стало очевидно, что оно сопряжено со своими сложностями и проблемами.

    * 🤯 Процесс создания образов Docker иногда приводил к сбоям, заставляя нас ломать голову. * 🔒 SSH-подключения к виртуальной машине иногда неожиданно прерывались, что приводило к неприятным задержкам в процессе развертывания. * ⌛ Тайм-ауты стали обычным явлением, что еще больше усугубило проблемы с развертыванием.

    Было ясно, что наша первоначальная попытка была далека от того бесшовного решения, к которому мы стремились.

    Спаситель в облаке ☁️

    В поисках более эффективного решения для развертывания и оптимизации совместной работы мы наткнулись на Cloud Run, который изменил правила игры на нашем пути развертывания.

    Вот некоторые ключевые функции, которые мы использовали:

    Автоматическое развертывание с GitHub 🚀

    • Бесшовная интеграция с GitHub.
    • Триггеры Cloud Build для автоматической сборки и развертывания.

    Контейнеризация стала проще 🐳

    • Dockerfile для определения среды и зависимостей.
    • Автоматическое создание и развертывание контейнеров.

    Автоматическое масштабирование для повышения эффективности ⚖️

    • Динамическое масштабирование на основе входящих запросов.
    • Экономичное распределение ресурсов.

    Извлечение кода с GitHub 🔄

    • Совместная работа членов команды в режиме реального времени.
    • Автоматическое развертывание внесенных изменений.

    Экономичность 💰

    • Модель ценообразования с оплатой по мере использования.
    • За простой не взимается плата.

    Надежный мониторинг и журналирование 📊

    • Подробные журналы и показатели.
    • Интеграция с инструментами мониторинга, такими как Stackdriver.

    Решение – реализация: :stuck_out_tongue_winking_eye:

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

    На этом этапе решения мы пройдем

    • Настройка Docker для вашего проекта
    • Настройка файлов Apache и сервера для бесперебойной работы вашего приложения в облаке
    • И в конце настройка запуска облака.

    Шаг 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 для размещения этого статического сайта в облаке

    
    
    • ==Теперь добавьте файл конфигурации 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 для своего проекта.

    Cloud Run API

    * ==Вы сможете увидеть, как здесь движется облако, как показано на изображении ниже.==

    Cloud Run * ==Теперь создайте облачную службу запуска==

    Create Cloud Run Service

    * ==Заполните данные и выберите вариант облачной сборки==

    Заполните детали * ==Выберите репозиторий и ветку и настройте файл докера в опции==

    Repo and Branch

    Build configuration

    * ==Теперь нажмите «Сохранить» и все.== * ==Теперь начнется сборка, и вы сможете увидеть ее в разделе облачной сборки.==

    Cloud build

    * В конце после успешной сборки вы можете проверить свое веб-приложение на внешнем IP-адресе, предоставленном облаком.

    Web application on external IP

    Путешествие :car:

    В этом блоге описывается наш путь от сложного процесса развертывания к оптимизированному и эффективному решению с использованием Cloud Run. Благодаря таким функциям, как автоматическое развертывание, контейнеризация, автоматическое масштабирование и экономическая эффективность, Cloud Run стал жизненно важным инструментом в нашем арсенале разработчиков. Попрощайтесь с проблемами развертывания и воспользуйтесь Cloud Run для более удобной разработки. ☁️🚀


    Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE