My container fetish

A long time ago, in secondary school my computer was a Swiss army knife. I had to install everything I needed, even if I needed it only for a weekend. The worst part is that when you install a python package for that one file in one project, you hit the pip install, and then keep the packages forever. I always thought "ah man, I should clean this". Then I met with Docker. Wrap your dependencies in one image. I thought "hm, interesting, but is it an issue to install those dependencies?" Then I worked in a team, where we had a development container, and each random package that we ever used was in a Docker image. And I thought "wow, interesting". Then I played some round with a game, called Kubernetes, where the hardware became something like the air for the sound. It was only just a medium. My thought was "wow, it's amazing".

So if you want to get the reasons why you should use Docker, you can find the answer on the internet. Just type "why I should use Docker" in your favourite search engine. I am just a notorious containerizing person. So when I decided to create my first mobile app, then I knew that my first step to start the development is creating a devcontainer.

My uneducated guess

I have never created mobile app before. But I made some experiments with the React JS and I had some work with REST API writing. So I chose the lazy solution, I wanted the React Native to be part in my stack. I started to catch up the basics of the web dev by taking Angela's course where the backend was written in express. I used that in a hackathon previously, so I thought the best opportunity is to rest my basic FastAPI knowledge and use express. I knew all thing that I need is just creating a typical Node JS docker image. I think it's pretty common in web development.

The final test that I want to pass

I assumed I would do multiple projects with React Native, so I decided I create a template repository for this. I always define some test tasks as a goal when I create a Docker image. Being totally newbie in React Native, I looked around on the internet. What could be better goal for a React Native devcontainer, than being able to run the Hello World React Native project? I read how I can start with the React Native Hello World app. I had no experience with the debugging in this field, so I exclude that from the scope.

I usually use the vscode while coding. It supports the dockerized dev environments, so I focus on creating a vscode dev environment, so I follow the .devcontainer folder convention, use the Microsoft dev images without regret.

"Keep It Simple Stupid" principle saved me

To be honest, my goal was not so simple as I described above. I overthought. I wanted a devcontainer, where I can run my React Native app in an Android emulator. I could run the Android Studio in the container with UI, but to create an emulator, run my code on that was too big bite for me. After that I realized the expo's solution with running the app on my phone via the expo app is so simple, and so enough for me. And the recipe for this had been already on the internet. Following Navneet's instructions, I created my dev container. The Hello World app ran, everything was totally fine.  But later when I tried to run my custom app, instead of the Hello World, the expo app on my phone could not connect to the server.

The Missing Piece

Error starting ngrok: Please install @expo/ngrok@^4.1.0 and try again, or try using another hosting method like lan or localhost
While running expo start --tunnel

It was strange, because the @expo/ngrok package was installed in the container. But the solution was simple. The ```expo start --tunnel``` runs the ngrok to create the tunnel, and somehow my default timeout threshold was too small. So I just added a line to my Dockerfile to increase the timeout threshold.

RUN yarn --network-timeout 100000

The last demand was the REST API. I wanted to run the backend server in the same container at least during the development phase. I ran my express backend with the ```node app.js``` command. Everything was fine, the only question was how could I reach the backend from the frontend. Well, the ports are forwarded from the container, so I was able to reach the backend via localhost:<given_ports>. But while the app is running on my phone, this is not enough, because the localhost means your smartphone's localhost. But as I said, everything is forwarded, so I just used my computer's LAN IP address as an address in the frontend code.

That's it folks. That was the story of my first containerized React Native + Express development environment. A basic Node JS Microsoft vscode Docker image is fine, just install the expo and the expo/ngrok in it. And be careful with the timeout threshold.