Couple of years back, I've made this awesome project:
Basically, its a controller, that extract 6-DOF values from hand-motions, using a regular 2D camera. And I took it very seriously, because it was my first project and all.
- I've consulted with some friends for Design Patterns advice. (back in the day, it was a confusing thing for me).
- I've cooked a tracking algorithm.
- I even have used some advanced OpenCV functionality:
- HaarCascade for face detection.
- And more.
Here, you can see all that in a nice UML I've made (also, by the book):
And then she came.
I talked about this project with everyone, it was my baby, and more I talked about it, the more it became famous, well at-least among the Tello community. Because that where I've used this controller. Though it can used anywhere (I told you guys, it is SOLID).
It has 31 starts and 13 forks on github. I mean, WOW, right?
Everyone was happy, until that one guy (in this case, a girl, a friend of a friend. That apparently she is an experienced software developer).
As usual I bragged about my beautiful, perfectly designed project.
And while telling her how I (bravely) overcame all obstacles regarding with the libraries installations, she asked me:
"Why haven't you built a docker for this project?"
I'll never forget that filling, where you think you are on the top of the world, and then someone sucker-punch you. yep, It was embarrassing.
I tried to explain why, but mostly I found myself mumbling gibberish. The fact is, I didn't even knew what DOCKER is.
Years have passed.
And I've found myself at home, due to the CORONAVIRUS, a perfect time to learn DOCKER.
To be honest, it is quite simple to get started. But before that, a short brief:
Docker is a platform for developers and sysadmins to build, run, and share applications with containers. The use of containers to deploy applications is called containerization. Containers are not new, but their use for easily deploying applications is. Also, from this site.
To get my hands around docker, I've found that it is a great opportunity to refer the elephant in this post (me, being arrogant, than horribly embarrassed) and build my old project a docker.
git clone https://github.com/GalBrandwine/HalloPy.git cd Hallopy
Create a Dockerfile in
/path/to/Hallopy, and put in it:
# Use the official image as a parent image FROM ubuntu:latest # Set the working directory WORKDIR /usr/src/app # Install any needed packages specified in requirements.txt RUN apt-get update RUN apt-get install -y pkg-config RUN apt install -y python3-dev RUN apt-get install -y python3-pip # AV library dependencies RUN apt-get install -y libavformat-dev libavdevice-dev RUN apt-get install -y libsm6 libxext6 libxrender-dev # Tello library dependencies RUN pip3 install av==6.1.2 # Library for communicating with the Tello drone RUN pip3 install tellopy # OpenCV RUN pip3 install opencv-python # Copy the rest of your app's source code from your host to your image # filesystem. COPY . . # Run hallopy controller, this will be executed from within a container. CMD ["python3","./hallopy/hallo.py"]
Build the docker with
docker build --network=host --tag hallopy:1.3 .
--network=host flag is giving the docker image (in this case
UBUNTU:LATEST) network access, so it can download all other libraries my project need. Building takes some time, depends on the machine horsepower & internet connection speed.
Running the container.
(make sure you are connected to the TELLO wifi)
xhost + && docker run --rm -it \ --privileged \ --net=host \ --ipc=host \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v /dev/video0:/dev/video0 \ --name hallopy \ hallopy:1.3
Commands and flags explanation:
xhost +- Allow any user to connect to the X server. That means programs can open graphical windows by their own. While usually, the user (us humans), press a button to do so.
docker run- Running a container from a built docker.
--rm- Automatically clean up the container and remove the file system when the container exits.
-it- For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it.
--privileged- Docker will enable access to all devices on the host. I have needed this to access the camera of the laptop. Later I saw the
-device=: That allows you to run devices inside the container without the
--net=host- The host setting will result in the container using the same UTS namespace as the host. I need this because the communication with the Tello is via WIFI.
--ipc=host- IPC (POSIX/SysV IPC) namespace provides separation of named shared memory segments, semaphores and message queues.
host- Use the host system’s IPC namespace.
-e DISPLAY=$DISPLAY- set any environment variable. In my case, I needed to provide the container where to open the GUI, e.g where/what is the screen.
-v /tmp/.X11-unix:/tmp/.X11-unix- Bind mount a volume. Ubuntu uses the X11 server for its graphics, and it acts as a file system. So I've needed to tell the container to mount this file system, in order to Access X11 server.
-v /dev/video0:/dev/video0- In Ubuntu, devices are also treated as file systems, so I've notified where is my laptops camera. (For some it might be video1)
--name hallopy- Give a name to the container (otherwise the name is randomly given).
hallopy:1.3- Run the actually docker image.
Summ-up & conclusions:
Dockers are FUN.
It took me 2 days to learn how to build this quite complex docker, that uses host internet connection , X11 server, has camera access, and many more cool stuff.
I'm sure that this will be useful in the future, mostly because I'm going through all Tensorflows tutorials these days, and Its simpler to run container with tensorflow & gpu access, than to install all the necessary dependencies for working with tensorflow & gpu on the machine itself (from experience, it is hell).
However, there are some down-sides to this so called cool discovery of mine. Now that I have a docker for my good old Hallopy project. I can share with you guys that after building the docker, the image has a size of 1.2GB, and for what?!
All I needed is 3 libraries: OpenCV, TelloPy, Numpy.
Why 1.2GB? because It downloaded a whole Ubuntu, just for me.
While I'm sure that there's some slim Ubuntu images out there. I didn't searched for them for I have got the experience I've wanted.
Docker Is very powerful. But not necessary for every project.