How I Utilize Docker for Flutter

Muhammad Ridho Ananda
6 min readApr 14, 2020

--

https://cdn-images-1.medium.com/max/1600/1*9hGvYE5jegHm1r_97gH-jQ.png

Hello everyone! As you might know from my previous articles, I and my teammates are currently building a mobile application named BuildFocus. Before diving deeper on how Docker is used for our application, I would like to tell about our software architecture. You can see it below:

  1. Android application, it is used to display our application to users. For this one, we use Flutter.
  2. Backend application, it is used to handle the logic and create endpoints of our application, such as saving or querying data from the database. For this one, we use Django REST. As the host for backend side, we use Heroku server.
  3. Database server, as the name database indicates, it is used to store users’ data, such as users’ achievements and tasks. Currently, we use PostgreSQL. We use PostgreSQL service from Heroku.
  4. Firebase Authentication, it used to handle users’ authentication with ease. We use this because one of our client’s requirement is to be able to login using social media (Google and Facebook).

How those components “talk” to each other?

  1. Flutter use Firebase Authentication for social media login (Google and Facebook). If login succeeds, Firebase Authentication will give corresponding user’s data such as email and profile image url.
  2. We create several APIs using Django REST. Then, Flutter can send a corresponding http request to REST endpoint. In return, REST will send a jsonfile response indicating the result of the request.
  3. We create the logic using Django on how PostgreSQL should update or query its database according to a specific request.

For visualization, you can see it on below diagram!

Software architecture in BuildFocus

About Docker

Now, let’s start to talk about Docker. You may have seen or read about Docker several times, but what it is exactly? First, we have to understand the technology behind Docker: containerization. A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. In other words, containerization allows app to be run quickly within different environment without the need of installing our app’s dependencies, as they already bundled within our container.

So, Docker basically is a container for apps. With Docker, you can treat containers like extremely lightweight, modular virtual machines. And you get flexibility with those containers. You can create, deploy, copy, and move them from environment to environment.

Before jumping on how we use Docker, you have to know some Docker related terms below, since I’m going to mention them a lot:

  • Dockerfile: A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. In In other words, Docker can build images automatically by reading the instructions from Dockerfile.
  • Docker Image: the building blocks of an application to be containerized. We can think of this as the “source code” for containers.
  • Docker Registry: the place where Docker images are stored. Docker offers Docker Hub, which is a cloud-based registry service that includes private and public image repositories.
  • Docker Container: each container is an instance of running Docker image.

Using Docker for BuildFocus

For my software architecture, we only use our own docker image for mobile application side (the one written with Flutter). For Firebase Authentication, obviously we don’t need docker. Meanwhile for backend side we use python:3.6 docker image and for deployment to database server we use ruby:2.4 docker image.

First of all why do we use Docker? That is because we need to do CI/CD (Continuous Integration / Continuous Delivery) with GitLab (we use GitLab for our remote repository). This CI/CD consists of lintering, unit testing, and integration with SonarQube. To do this, our application will be run by GitLab server. Now, we need to tell the GitLab environment about our app dependencies (ex: what version of Flutter do we use) without unnecessary hassle. Fortunately, we have Docker!

How We Use Our Own Docker

  • Write Dockerfile

First of all, you have to define your Docker. You can do this by writing your own Dockerfile. Below is the Dockerfile currently used for my Flutter project:

#1
FROM openjdk:8-jdk
#2
ENV FLUTTER_VERSION="https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.12.13+hotfix.8-stable.tar.xz" \
SONAR_SCANNER_CLI="https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.2.0.1873-linux.zip" \
SONAR_SCANNER_VERSION="4.2.0.1873-linux"
#3
RUN apt-get update && apt-get install apt-transport-https
RUN wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list
RUN apt-get update && \
apt-get install dart
ENV PATH="$PATH:/usr/lib/dart/bin"#4
RUN wget -q --output-document=flutter-sdk.tar.xz ${FLUTTER_VERSION} && \
tar -xf flutter-sdk.tar.xz && \
rm flutter-sdk.tar.xz
ENV PATH=$PATH:/flutter/bin
RUN flutter doctor -v#5
RUN wget -q --output-document=sonar-scanner-cli.zip ${SONAR_SCANNER_CLI} && \
unzip sonar-scanner-cli.zip && \
rm sonar-scanner-cli.zip
ENV PATH=$PATH:/sonar-scanner-${SONAR_SCANNER_VERSION}/binRUN sonar-scanner --help#6
RUN apt-get update -q && apt-get install -y --no-install-recommends apt-utils
RUN apt-get install -y lcov

Block #1 tells what base image you want to use. Block #2 defines environment variables that will be used for this Dockerfile. Block #3 tells Docker to install Dart with stable version. Block #4 tells Docker to install Flutter with the version defined on the environment variable. Block #5 tells Docker to install SonarQube with the version defined on the environment variable. Block #6 tells Docker to install lcov. We need to install lcov since it is required to display code coverage in Flutter.

  • Build docker image

After you’ve done writing your Dockerfile, the next step is to build your docker image by running docker build command in your command line. The image building process may take some time. When you’ve successfully built your image, you can check your image ID by running docker images command. You will see something similar like this:

The next step is to tag your image. Choose your image ID and then run docker tag. For example, I want to tag my latest image to my Docker Hub repository, so I run this command:

Here, the ID d46c01bbcd61must match the image ID, which indicates the source image. mridho2828/ppl2020b2 is my Docker Hub repository and :latest indicates the tag. In general, a good choice for a tag is something that will help you understand what this container should be used in conjunction with, or what it represents. As you can see, when you run docker images the repository and tag of my image is updated.

  • Push docker image to docker registry

If you use Docker Hub, you have to login first. Simply run docker login command and then enter your username and password. If everything works, you will get a successful login message. The last step, is to push your image to Docker Hub by running docker push command. For my docker image above, I run docker push mridho2828/ppl2020b2:latest to indicate which image I want to push.

Now, your image is available on Docker Hub and can be used by anyone, as long as you set it as a public image. For example, in our project, we can tell GitLab to use this image by specifying it in .gitlab-ci.yml file. GitLab server will then pull our image. Then, a docker container instance will run our image.

By the way, if you need further explanation about docker commands, just read the official docker documentation here.

Conclusion

Docker is an exceptionally useful tool for developers to encapsulate their application with its dependencies. We don’t have to worry anymore about running the application within different environment. Docker is utilized by developers in so many ways, therefore it is no surprise that Docker is very popular among developers.

That’s all about using Docker for my Flutter application, I hope that can give you a brief example on how Docker is used on software development. Thank you for reading, stay safe, #stayathome.

References

  1. https://www.redhat.com/en/topics/containers/what-is-docker
  2. https://ropenscilabs.github.io/r-docker-tutorial/04-Dockerhub.html
  3. https://medium.com/@sonofkyrat99/beginning-the-containerization-journey-with-docker-9583b655b06f

--

--