How to create a "DOckerfile" to containerize a "Flutter" app to deploy it on a Kubernetes cluster? - flutter

I am just wondering to know how should I create a docker file for a Flutter app then deploy it on a Kubernetes cluster?
I found the following Dockerfile and server.sh script from this website but I am not sure if this a correct way of doing it?
# Install Operating system and dependencies
FROM ubuntu:22.04
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
# download Flutter SDK from Flutter Github repo
RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter
# Set flutter environment path
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"
# Run flutter doctor
RUN flutter doctor
# 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
# Record the exposed port
EXPOSE 5000
# make server startup script executable and start the web server
RUN ["chmod", "+x", "/app/server/server.sh"]
ENTRYPOINT [ "/app/server/server.sh"]
And:
#!/bin/bash
# Set the port
PORT=5000
# Stop any program currently running on the set port
echo 'preparing port' $PORT '...'
fuser -k 5000/tcp
# switch directories
cd build/web/
# Start the server
echo 'Server starting on port' $PORT '...'
python3 -m http.server $PORT
I did all the steps and it seems it works fine but as long as I use skaffold I don't know how/where to put the following command to automate this step as well (I have already ran this command manually):
docker run -i -p 8080:5000 -td flutter_docker
I still like to know was the above files, proper/official way to doing that or there is a better way of it?
EDIT: I created the following deployment & service file to put the deploy the created image on Kubernetes local Kind cluster but when I run kubectl get pods I can not find this image but I find it by doing docker images. Why this happens and how can I put in on a Kubernetes pod instead of docker images?
apiVersion: apps/v1
kind: Deployment
metadata:
name: client-depl
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: client
image: front
---
apiVersion: v1
kind: Service
metadata:
name: client-srv
spec:
selector:
app: client
ports:
- name: client
protocol: TCP
port: 3000
targetPort: 3000

The question (title) is misleading.
There are 2 parts.
How to containerize the app (in this case flutter app).
How to deploy the app on the k8s cluster.
To deal with the first part, You have Dockerfile. There is room for improvement but I think this Dockerfile should work. Then you need to build a container image. Please refer to the official documentation. Finally, you need to push this created container image to some repository. (We may skip this pushing stage but to make things simple I am suggesting pushing the image)
For the second part, you should be familiar with basic Kubernetes concepts. You can run the container from a previously built container image with the help of the k8s Pod object. To access the application, you need one more k8s object and that is the Service (Load balancer or Node port type).
I know things are a bit complex (at initial levels) but please follow a good course/book I have gone through the blog post you shared, and this talks only about the first part and not the second part. You will have a container image at the end of this blog post.
I suggest going through the free playground offered by killer shell, if you don't want to set up a k8s cluster on your own, that is again another learning curve. Skip the first tile on this page this is just a playground, but from the second tile, they have enough material.
Improvements for Edited Question:
server.sh: maintaining a startup script is quite standard practice if you have complex logic to start the process. We can skip this file but in that case, a few steps will be added to Dockerfile.
kubectl get pods does not show you images but it will show you running pods in the cluster (in default namespace). Not sure how you ran and connected to the cluster. But try to add output of the command.
few pointers to impve dockerfile:
Use a small base image footprint. Ubuntu: xx has many packages pre-installed, maybe you don't need all of them. Ubuntu has slim images also or try to find a flutter image.
Try to reduce Run statements. you can club 2-3 commands in one. this will reduce layers in the image.
instead of RUN git clone, you should clone code before docker build and copy/add code in the container image. In this way, you can control which files you need to add to the image. You also don't require to have a git tool installed in the container image.
RUN ["chmod", "+x", "/app/server/server.sh"] and RUN mkdir both statements are not needed at all if you write Dockerfile smartly.
Dockerfiles should be clean, crisp, and precise.
PS: Sorry but this is not a classroom section. I know this is a bit complex thing for beginners. But please try to learn from some good sources/books.

Related

Deploy a private image inside minikube on linux

I am starting to use kubernetes/Minikube to deploy my application which is currently running on docker containers.
Docker version:19.03.7
Minikube version: v1.25.2
From what I read I gather that first of all I need to build my frontend/backend images inside minikube.
The image is available on the server and I can see it using:
$ docker image ls
The first step, as far as I understand, is to use the "docker build" command:
$docke build -t my-image .
However, the dot at the end, so I understand, means it is looking for a Dockerfile in the curretn directoy, and indeed I get an error:
unable to evaluate symlinks in Dockerfile path: lstat
/home/dep/k8s-config/Dockerfile: no such file or directory
So, where do I get this dockerfile for the "docker build" to succeed?
Thanks
My missunderstanding...
I have the Dockefile now, so I should put it anywhere and use docker build from there.

I can't run a simply Ubuntu Container on Google Cloud Kubernetes!! It just allow to run containers which is hosting a webserver... ONLY?

first I would like to thank you for been here! I hope you doing well!
So... I'm trying to create an Ubuntu:20.04 container on Google Cloud Run or Kubernetes..
Whenever I try to deploy this Dockerfile on Google Cloud Run
FROM ubuntu:20.04
RUN apt-get update
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
It fails, and shows an error:
The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable
Apparently, this happens due to lack of a webserver inside the container?
To fix this, I followed this guideline by Google itself.
So, basically, inside the Dockerfile, I just added couple of code lines:
It just installs python, flask and gunicorn and set default to automatically run app.py when container is created.
FROM ubuntu:20.04
RUN apt-get update
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
RUN apt-get install -y python3 && apt-get install -y pip && pip install Flask gunicorn
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
Also, I created a new file "app.py" that import Flask.
Its just a simple webserver...
# Python run this file, and when someone send a request to this Ubuntu:20.04 container ip on port 8080
# a simple text is showed "Hello World".
import os
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
target = os.environ.get('TARGET', 'World')
return 'Hello {}!\n'.format(target)
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))
And boom... It works!! We have Ubuntu:20.04 running on Google Cloud Run... the error was fixed!
So, Google Cloud Run works like:
if there's a webserver running on that port:
then GCR LAUNCH CONTAINER
if there's NO webserver running on that port:
GCR DOESN'T launch container...
IN RESUME:
I just want to run a python code on ubuntu container.
just like I run in my local machine, that works perfectly.
also this python code doesn't use flask or any webservice, it runs independently, make some compute works and comunicate through an external database.
So, my question is, how to deploy a container image that doesn't host a web service, on Google Cloud Run or Kubernetes, just like I create on my local machine and acess through /bin/bash CLI...???
So, my question is, how to deploy a container image that doesn't host a web service, on Google Cloud Run or Kubernetes, just like I create on my local machine and access through /bin/bash CLI...???
There might be a misunderstanding of the Google services here.
Google Cloud Run
Runs your web application (a web server) in a container. It is not a service for other things than web applications (e.g. only http).
Key features: Keeps your server up and running, and can scale out to multiple instances.
Google Kubernetes Engine
Runs services (processes that starts and then are meant to stay running) in containers, both stateless, as Deployment and stateful as StatefulSet. Also support for jobs that is tasks that perform something and then terminates.
Key features: Keeps your server up and running, and can scale out to multiple instances. Can re-run Jobs that failed.
Google Compute Engine
If no one of the above fits your needs, you can always go low level and run and maintain virtual machines with e.g. Linux and containers on it.

How to run docker-compose on google cloud run?

I'm new to GCP, and I'm trying to deploy my spring boot web service using docker-compose.
In my docker-compose.yml file, I have 3 services: my app service, mysql service and Cassandra service.
Locally, It works like a charm. I added also a cloudbuild.yaml file :
steps:
- name: 'docker/compose:1.28.2'
args: ['up', '-d']
- name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'workspace_app:latest', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA']
images: ['gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA']
The build on Google cloud build is made with success. But, when I try to run the image on google cloud run, It doesn't call the docker-compose.
How do I must process to use docker-compose on production?
With Cloud Run, you can deploy only one container image. The container can contain several binaries that you can run in parallel. But keep that in mind:
CPU is throttled when no request are processed. Background process/app aren't recommended on Cloud Run, prefer Request/Response app on Cloud Run (a webserver).
Only HTTP request are supported by Cloud Run. TCP connection (such as MySQL connection) aren't supported.
Cloud Run is stateless. You can't persist data in it.
All the data are stored in memory (directory /tmp is writable). You can exceed the total size of the instance memory (your app footprint + your files stored in memory)
Related to the previous point, when the instance is offloaded (you don't manage that, it's serverless), you lost all what you put in memory.
Thus, MySQL and Cassandra service must be hosted elsewhere
docker-compose -f dirfile/ cloudbuild.yaml up
and for check it write this command
docker images
and for check you conatiner
docker container ls -a
and for check if container run or not write this command
docker ps
Finally, I deployed my solution with docker-compose on the google virtual machine instance.
First, we must clone our git repository on our virtual machine instance.
Then, on the cloned repository containing of course the docker-compose.yml, the dockerfile and the war file, we executed this command:
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD:$PWD" \
-w="$PWD" \
docker/compose:1.29.1 up
And, voila, our solution is working on production with docker-compose

How to deploy desktop based application on kubernetes

I want to deploy my desktop based application on Kubernetes. Can someone suggest some ways of doing it.
In Docker we used --net and --add-host for running same. But in Kubernetes we are not able to find any solution.
Please help!
There are a bunch of desktop applications with dockerfiles to run on Linux Desktops.
I am not sure if it is possible but the idea is to deploy Desktop-based(GUI applications) to kubernetes you need to consider a few things.
You need to make sure kubernetes nodes are Desktops not the server otherwise it wont work.
mount the node's x11 socket inside container running desktop application to allow x11 connection.
--volume /tmp/.X11-unix:/tmp/.X11-unix
export node's DISPLAY environment variable to container DISPLAY.
-e DISPLAY = unix$DISPLAY
Here is a docker-compose file I use at my Desktop.
version: '3.0'
services:
eclipse:
container_name: naeemrashid/eclipse
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- /home/$USER/containers/eclipse/workspace:/home/eclipse/workspace
environment:
- DISPLAY=unix$DISPLAY

aspnetcore:2.0 based image won't run on AKS nodes?

I have an asp.net core 2.0 application whose docker image runs fine locally, but when that same image is deployed to an AKS cluster, the pods have a status of CrashLoopBackOff and the pod log shows:
Did you mean to run dotnet SDK commands? Please install dotnet SDK from:
http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409.
And since you can't ssh to AKS clusters, it's pretty difficult to figure this out?
Dockerfile:
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY . .
EXPOSE 80
ENTRYPOINT ["dotnet", "myapi.dll"]
Turned out that our build system wasn't putting the app code into the container as we thought. Since the container wasn't runnable, I didn't know how to inspect its contents until I found this command which is a lifesaver for these kinds of situations:
docker run --rm -it --entrypoint=/bin/bash [image_id]
... which at this point, you can freely inspect/verify the contents of the container.
I just ran into the same issue and it's because I was missing a key piece to the puzzle.
docker-compose -f docker-compose.ci.build.yml run ci-build
VS2017 Docker Tools will create that docker-compose.ci.build.yml file. After that command is run, the publish folder is populated and docker build -t <tag> will build a populated image (without an empty /app folder).