Flutter is a UI toolkit for building natively compiled applications for mobile, web, and desktop platforms with a single codebase. It represents the most recent effort towards what Java promised: a “Write Once, Run Anywhere” experience. Writing a single codebase that runs on many platforms offers a number of advantages. Traditionally, if an organization wanted to support their application on web, mobile, and desktop it would have to support 3 separate codebases all in different languages and technologies. Paying for 3 different engineering teams to support one product is an expensive proposition. Java was one of the first technologies that attempted to solve this problem but it was stymied by a number of challenges. These included a lack of support from certain major corporations, performance issues, and security issues. Luckily, Google has offered us Flutter as a promising candidate to bring about the reality of a truly crossplatform development experience.
Flutter’s support for the Web is still in the Beta stage of development. However, a number of organizations are already using it successfully for production sites. From an experience and functionality point of view, developing a Flutter app for the web is almost exactly the same as for any of the other platforms. The main thing that is different is how the app is served and deployed. Because Flutter for web is so new, users are discovering new ways of doing things all the time. In my own development, I am building an app designed around microservices that will eventually be deployed with Kubernetes. I wanted to serve my front end Flutter app just like any other front end from within a container but I couldn’t find any direct literature on doing this. After figuring out how to do it on my own I wanted to share it with the world, which is the purpose of this article.
I am fairly sure that someone who stumbles across this article will have been looking for it. Therefore, I assume basic knowledge of Docker, Flutter, and web development basics. However, in the spirit of helpfulness I will include links to important materials. I assume the reader is using Linux but the information is easily adapted to other platforms. As a general tip for reading new technical guides I always recommend that the reader reads the entire guide before following any setup steps.
When you are ready to implement you can see the source code here.
flutter create flutter_web_docker_example
cdinto the project directory
flutter run -d chrome
flutter build web while in the project directory. After this is done you will see a new folder in the
build directory in the project called
As you can see this looks sort of like a release folder for a standard web site. This entire
web directory needs to be served together. Make sure to inspect the
index.html file and notice that it specifies the script source to be
main.dart.js. This file is the compiled Flutter app. This is incredibly neat because a user could actually embed the Flutter app anywhere in any standard
html page and serve it how they like. Although I haven’t explored it further, I am sure some pretty cool stuff could be done using this technique.
At this point, we have convinced ourselves that all of the magic has been taken care of by Flutter and that all we need to do to serve the app is serve this
build directory. We will do this from inside a Docker container.
We will use a Dockerfile to specify our container. This Dockerfile will:
Let’s look at the Dockerfile now. I’ve clearly labeled what each section of commands does.
Before we start the Dockerfile we need to add the server script file to the project. It will be copied to the container with the rest of the app files. I am using a Python HTTP server for my development but any HTTP server can be used as long as it is installed and configured in the Dockerfile and is able to be started in this script. Add a folder called
server and a file inside it
server.sh to the app directory:
Add these contents to the
fuser is a Linux command that is used to kill processes on a port. There are similar commands in Windows so if you decide to run this file locally you should implement the equivalent Windows command. Notice that we start on port 4040 which is the same one that is exposed in the Dockerfile. This port can be changed as you need it as long as it is changed in the Dockerfile as well.
Now it is time to build and run the container to see the app being served from within it.
docker build . -t flutter_web_docker_example
This command will build a Docker image specified by the Dockerfile above and name it ‘flutter_web_docker_example’.
Let’s run the container and see our app being served!
cdinto the root project folder
docker run -i -p 8080:4040 -td flutter_web_docker_example
This docker run command binds the container port 4040 to the TCP port 808. See this link for more information on docker ports.
Now if you go to the Docker view in VSCode you should see our container running:
The app is now running on localhost:8080 . Navigate there in a browser to see the app!
You can find the source code for this project here.
This article demonstrated how to serve a Flutter web app from a container. This technique can be used to deploy Flutter web apps in the could using container hosting services. This technique lends itself to microservice architectures and offers the ability to make smooth and homogeneous deployments.
Drop me a line at firstname.lastname@example.org to chat!
I am also an aspiring Twitter mob leader. Join me!