2

I have been trying to deploy my application on elastic beanstalk but it keeps failing. I tried to to deploy it on AWS ECR + Fargate and GCP Cloud Run and it works without any problem. I have also tried to set it to immutable and still fail.

Here's my Dockerfile

#Stage 1 - Install dependencies and build the app
FROM debian:latest AS build-env

# Install flutter dependencies
RUN apt-get update 
RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback lib32stdc++6 python3
RUN apt-get clean

# Clone the flutter repo
RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter

# Set flutter path
# RUN /usr/local/flutter/bin/flutter doctor -v
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"

# Run flutter doctor
RUN flutter doctor -v
# Enable flutter web
RUN flutter channel master
RUN flutter upgrade
RUN flutter config --enable-web

# Copy files to container and build
RUN mkdir /app/
COPY . /app/
WORKDIR /app/
RUN flutter build web

# Stage 2 - Create the run-time image
FROM nginx:1.21.1-alpine
COPY --from=build-env /app/build/web /usr/share/nginx/html

It crash somewhere around step 7.

Step 7/18 : RUN flutter channel stable
 ---> Running in af4a4105e884
[91mDownloading Linux x64 Dart SDK from Flutter engine 4e6cbe0fc22d0a7c3f3380dff23ad2cad84b2170...
[0m  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0  198M    0 28911    0     0   159k      0  0:21:12 --:--:--  0:21:12  158k
 53  198M   53  106M    0     0  92.3M      0  0:00:02  0:00:01  0:00:01 92.2M
100  198M  100  198M    0     0   107M      0  0:00:01  0:00:01 --:--:--  107M
[91mBuilding flutter tool...
[0mResolving dependencies...
Got dependencies.
[91m
===== CRASH =====
si_signo=Bus error(7), si_code=2, si_addr=0x7fafc3d69000
version=3.0.0-300.0.dev (dev) (Sat Mar 4 11:55:16 2023 -0800) on "linux_x64"
pid=212, thread=218, isolate_group=kernel-service(0x7fb004035d10), isolate=kernel-service(0x7fb0040144e0)
os=linux, arch=x64, comp=no, sim=no
isolate_instructions=7fb008b5f000, vm_instructions=556d3f931380
fp=7faff5ffd1c0, sp=7faff5ffd178, pc=7fb010d3f733
  pc 0x00007fb010d3f733 fp 0x00007faff5ffd1c0 /lib/x86_64-linux-gnu/libc.so.6+0x18b733

===== CRASH =====
si_signo=Bus error(7), si_code=2, si_addr=0x7fafc794f040
Aborting reentrant request for stack trace.
[0m[91m/usr/local/flutter/bin/internal/shared.sh: line 178:   212 Aborted                 (core dumped) "$DART" --verbosity=error --disable-dart-dev $FLUTTER_TOOL_ARGS --snapshot="$SNAPSHOT_PATH" --snapshot-kind="app-jit" --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.json" --no-enable-mirrors "$SCRIPT_PATH" > /dev/null
[0m
2023/03/07 17:39:54.516708 [INFO] Building app-prod
The command '/bin/sh -c flutter channel stable' returned a non-zero code: 134

2023/03/07 17:39:54.577381 [WARN] failed to execute command: docker-compose build, retrying...
2023/03/07 17:39:54.577428 [INFO] Running command /bin/sh -c docker-compose build
2023/03/07 18:00:11.377269 [INFO] Sending build context to Docker daemon  580.1kB Step 1/18 : FROM ubuntu:20.04 AS builder

Many of my apps like React, NodeJS are running on Elastic Beanstalk. I want my flutter web to run on Elastic Beanstalk as well.

xreyc
  • 203
  • 2
  • 8

1 Answers1

1

Seem's like Elastic Beanstalk was not able to properly build the Flutter web application. But after days of experimenting, I finally was able to deploy my Flutter Web Application to ELB.

What I did is that I added a new layer to the deployment process by using Github actions and ECR.

Here's the flow of my CI/CD process:

  1. Flutter build for web will happen on Github actions instead of building it inside elastic beanstalk.
  2. After the build is done, GitHub actions will push the build image on AWS ECR.
  3. After a successful push to ECR, we will have to push our project code to s3 in zip format so that Elastic beanstalk will be able to pull the files that contains docker-compose. Our project must contain docker-compose.yml which will be executed by elastic beanstalk later.
  4. Then GitHub actions will trigger elastic beanstalk to pull the zip file from s3 that container docker-compose.yml file.
  5. Elastic beanstalk will automatically run the docker-compose.yml which pull the image from ECR.

DOCKERFILE

Before anything else, make sure that your project is running Flutter Stable version 3.7.7 or the latest stable version so that our Dockerfile will not encounter some errors. To check run flutter doctor. inside our root project create a file named Dockerfile then copy and paste the following:

#Stage 1 - Install dependencies and build the app
FROM debian:latest AS build-env

# Install flutter dependencies
RUN apt-get update 
RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback lib32stdc++6 python3
RUN apt-get clean

# Clone the flutter repo
RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter

# Set flutter path
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"

# Enable flutter web
RUN flutter channel stable
RUN flutter upgrade
RUN flutter config --enable-web

# Copy files to container and build
RUN mkdir /app/
COPY . /app/
WORKDIR /app/
RUN flutter build web

# Stage 2 - Create the run-time image
FROM nginx:1.21.1-alpine
COPY --from=build-env /app/build/web /usr/share/nginx/html

AWS ECR

Go to AWS ECR ang create a repository for your image.

  1. Copy the repository name, ex: projectrepo1
  2. Copy the URI ex: ACCNUM.dkr.ecr.REGION.amazonaws.com/projectrepo1

DOCKER-COMPOSE.YML

On root folder of your application, create a docker-compose.yml file, this will will be executed by elastic beanstalk. Inside docker-compose.yml paste the following, then replace the image with the URI we copied before. you can name the container anything you want.

version: "3.8"
services:
  flutterweb:
    image: ACCNUM.dkr.ecr.REGION.amazonaws.com/projectrepo1
    container_name: flutterweb_container1
    ports:
      - '80:80'

ELASTIC BEANSTALK

Create a new elastic beanstalk and select Docker as platform.

  1. Copy the application name
  2. Copy the environment name

USER AND USER GROUP

  1. Go to IAM
  2. Create a user group and add the following Policy AmazonEC2ContainerRegistryFullAccess, AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk, AmazonElasticContainerRegistryPublicFullAccess
  3. Add new user and that user to the user group
  4. Generate ACCESS KEY and SECRET KEY for the user, make sure you copy.

ELASTIC BEANSTALK ECR ACCESS

  1. Go to IAM Roles
  2. Look for aws-elasticbeanstalk-ec2-role and open that role. add the following policy for that role, AmazonEC2ContainerRegistryFullAccess

This will enable elastic beanstalk to access our Container registry.

GO TO YOUR GITHUB PROJECT AND ADD A SECRET

  • AWS_ACCESS_KEY_ID : YOUR ACCESS KEY
  • AWS_SECRET_ACCESS_KEY: YOUR SECRET KEY

GITHUB ACTIONS

On our root folder, create a forder named .github, inside it create another folder named workflows, inside workflows create a file named deploy-aws.yml. It should look like this, .github/workflows/deploy-aws.yml

Inside deploy-aws.yml paste the following:

name: Deploy Flutter Web To AWS ELB
on:
  push:
    branches:
    - development
jobs:
  build:
    runs-on: ubuntu-latest
    steps:

    - name: Checkout source code
      uses: actions/checkout@v2

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: YOUR_ECR_REGION

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: YOUR_REPOSITORY_NAME
        IMAGE_TAG: latest
      run: |
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

    - name: Generate deployment package
      run: zip -r deploy.zip . -x '*.git*'

    - name: Deploy to EB
      uses: einaregilsson/beanstalk-deploy@v21
      with:
        aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        application_name: YOUR_ELASTIC_BEANSTALK_APPLICATION_NAME
        environment_name: YOUR_ELASTIC_BEANSTALK_ENVIRONMENT_NAME
        version_label: ${{ github.sha }}
        region: YOUR_ELASTIC_BEANSTALK_REGION
        deployment_package: deploy.zip

Make sure you replaced the following:

  • YOUR_ECR_REGION: ex: ap-southeast-1
  • YOUR_REPOSITORY_NAME: ex: projectrepo1
  • YOUR_ELASTIC_BEANSTALK_REGION: ex: ap-southeast-1
  • YOUR_ELASTIC_BEANSTALK_APPLICATION_NAME: ex: flutterweb
  • YOUR_ELASTIC_BEANSTALK_ENVIRONMENT_NAME: ex: flutterweb-env

This solution works for me. I'll add a new approach to this later using AWS Codebuild instead of Github actions.

xreyc
  • 203
  • 2
  • 8