Search code examples
azureflutterdockerazure-web-app-serviceflutter-web

Attempting to host a flutter project on Azure App Services using a docker image; local image and cloud image behave differently


I am having trouble with azure and docker where my local machine image is behaving differently than the image I push to ACR. while trying to deploy to web, I get this error:

ERROR - failed to register layer: error processing tar file(exit status 1): Container ID 397546 cannot be mapped to a host IDErr: 0, Message: mapped to a host ID

So in trying to fix it, I have come to find out that azure has a limit on uid numbers of 65000. Easy enough, just change ownership of the affected files to root, right?

Not so. I put the following command into my Dockerfile:

RUN chown -R root:root /usr/local/flutter/bin/cache/artifacts/gradle_wrapper/

Works great locally for changing the uids of the affected files from 397546 to 0. I do a command in the cli of the container:

find / -uid 397546

It finds none of the same files it found before. Yay! I even navigate to the directories where the affected files are, and do a quick

ls -n to double confirm they are fine, and sure enough the uids are now 0 on all of them. Good to go?

Next step, push to cloud. When I push and reset the app service, I still continue to get the same exact error above. I have confirmed on multiple fronts that it is indeed pushing the correct image to the cloud. All of this means that somehow my local image and the cloud image are behaving differently. I am stumped guys please help.

The Dockerfile is as below:

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 psmisc
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 upgrade
RUN flutter config --enable-web

# Run flutter doctor
RUN flutter doctor -v

# Change ownership to root of affected files
RUN chown -R root:root /usr/local/flutter/bin/cache/artifacts/gradle_wrapper/

# Copy the app files to the container
COPY ./build/web /usr/local/bin/app
COPY ./startup /usr/local/bin/app/server
COPY ./pubspec.yaml /usr/local/bin/app/pubspec.yaml

# Set the working directory to the app files within the container
WORKDIR /usr/local/bin/app
# Get App Dependencies
RUN flutter pub get
# Build the app for the web

# Document the exposed port
EXPOSE 4040
# Set the server startup script as executable
RUN ["chmod", "+x", "/usr/local/bin/app/server/server.sh"]

# Start the web server
ENTRYPOINT [ "/usr/local/bin/app/server/server.sh" ]```

Solution

  • So basically we have made a shell script to build web BEFORE building the docker image. we then use the static js from the build/web folder and host that on the server. No need to download all of flutter. Makes pipelines a little harder, but at least it works.

    New Dockerfile:

    FROM ubuntu:20.04 as build-env
    
    RUN apt-get update && \
           apt-get install -y --no-install-recommends apt-utils && \
           apt-get -y install sudo
    
    
    ## for apt to be noninteractive
    ENV DEBIAN_FRONTEND noninteractive
    ENV DEBCONF_NONINTERACTIVE_SEEN true
    
    ## preesed tzdata, update package index, upgrade packages and install needed software
    RUN echo "tzdata tzdata/Areas select US" > /tmp/preseed.txt; \
        echo "tzdata tzdata/Zones/US select Colorado" >> /tmp/preseed.txt; \
        debconf-set-selections /tmp/preseed.txt && \
        apt-get update && \
        apt-get install -y tzdata
    
    RUN apt-get install -y curl git wget unzip libstdc++6 libglu1-mesa fonts-droid-fallback lib32stdc++6 python3 python3 nginx nano vim
    
    RUN apt-get clean
    
    # Copy files to container and build
    RUN mkdir /app/
    COPY . /app/
    WORKDIR /app/
    RUN cd /app/
    
    # Configure nginx and remove secret files
    RUN mv /app/build/web/ /var/www/html/patient
    RUN cd /etc/nginx/sites-enabled
    RUN cp -f /app/default /etc/nginx/sites-enabled/default
    RUN cd /app/ && rm -r .dart_tool .vscode assets bin ios android google_place lib placepicker test .env .flutter-plugins .flutter-plugins-dependencies .gitignore .metadata analysis_options.yaml flutter_01.png pubspec.lock pubspec.yaml README.md
    
    # Record the exposed port
    EXPOSE 5000 
    
    # Start the python server
    RUN ["chmod", "+x", "/app/server/server.sh"]
    ENTRYPOINT [ "/app/server/server.sh"]