0

I am trying to inject URL while creating flutter build web. For Inject URL I am using environment variable. Docker file success fully create the docker image and docker container. But when I open web application on browser the environment variable is empty. I did not understand what I am missing. Previously I have no experience with docker That was my first time. Please Guide me what I am doing wrong.

To build docker image I am using command.

docker build . -t test-application

To run docker container I using command

docker run -ti -p 5000:4040 -e API_URL=example.com test-application

My docker file.

# Install dependencies
FROM debian:latest AS build-env
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 -b stable /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

# Run flutter doctor
RUN  flutter doctor -v

# Copy the app files to the container
COPY . /usr/local/bin/app

# Set the working directory to the app files within the container
WORKDIR /usr/local/bin/app

# Get App Dependencies
RUN  flutter clean

# Get App Dependencies
RUN  flutter pub get

# Build the app for the web
 RUN  flutter build web --release --dart-define API_URL=${API_URL:-}

# 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" ]

my server.sh file

#!/bin/bash
# Welcome
echo 'Server start script initialized'
    
# Set the port
PORT=4040

# Kill anything that is already running on that port
echo 'Cleaning port' $PORT
fuser -k 4040/tcp

# Change directories to the release folder
cd build/web/

# Start the server
echo 'Starting server on port' $PORT
python3 -m http.server $PORT

# Exit
echo 'Server exited...'

Getting my environment variable

static const baseUrl =
      "${const String.fromEnvironment("API_URL")}/public";
3
  • You are using your API_URL var to set a dart variable while building the image. Since the env var is not defined at that time, your RUN flutter build web ..... step uses an empty value as default (i.e. --dart-define API_URL=${API_URL:-}). When you start the container, you inject that var but the dart configuration is already done with an empty value which your String.fromEnvironment("API_URL") function will return. If you want to change and use that var at container launch time, you need to somehow integrate the dart variable config usage in your entrypoint script (or CMD) Commented Jan 7, 2022 at 8:10
  • can you help me how I can do that do you have any example. Commented Jan 7, 2022 at 8:25
  • I don't use/know flutter at all so I'm afraid I can only give bad advice. As a very naive try, I would move the flutter build ... command from the Dockerfile to somewhere in the entrypoint script. But I have absolutely no clue if this can be a good practice and how it will affect your container start time... I have no idea how flutter is actually launched/used by your server script. If this is at the step you start the http server with python, there might be some commands behind the scene where you can inject that dart var. I'm afraid that's all the help I'm able to provide on this subject. Commented Jan 7, 2022 at 8:36

1 Answer 1

1

To use a build argument, you need to add an ARG statement in your dockerfile. To also have it available at runtime, you can add an ENV statement, that sets an environment variable with the value of the build argument

# Install dependencies
FROM debian:latest AS build-env

# Add the following two lines
ARG API_URL
ENV API_URL=$API_URL

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 -b stable /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

# Run flutter doctor
RUN  flutter doctor -v

# Copy the app files to the container
COPY . /usr/local/bin/app

# Set the working directory to the app files within the container
WORKDIR /usr/local/bin/app

# Get App Dependencies
RUN  flutter clean

# Get App Dependencies
RUN  flutter pub get

# Build the app for the web
 RUN  flutter build web --release --dart-define API_URL=${API_URL:-}

# 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" ]

Then when you build, you add the value you want like this

docker build --build-arg API_URL=example.com -t test-application .

You then don't need to specify it at runtime unless you want to override it, so your run command becomes. Overriding it will only override the environment variable and won't change what was put into the image at build time, of course.

docker run -ti -p 5000:4040 test-application
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.