Deploying a nodejs app in fly.io and some struggles

This week I've been working on a side project to build and api wrapper for podcast index. .NET is my forte, but I want to try my hands on a new stack and chose expressjs. I've created some hello-world stuff in expressjs before, but this time I wanted to create a full-blown API.

Creating the API

API creation was comparatively straight forward. I picked typescript for expressjs and everything went smooth. I added morgan for minimal logging along with concurrently and nodemon. Also, I used swagger-ui-express and tsoa for swagger document generation. As always everything worked fine in local. 😂

Why Fly.io?

I chose fly.io because I heard good things about them and also it's recommended by James Longster for actual-budget. Their documentation was really good.

flyctl installation

Since I work from a windows machine, I had to install their command line tool for windows.

iwr https://fly.io/install.ps1 -useb | iex

I used powershell occasionally, still that looked like a strange command for me. Soon, I came to know that all these are just shorthand aliases. iwr is the shorthand for Invoke-WebRequest and iex is the shorthand for Invoke-Expression. So this command means that we send a web request to fetch the powershell file and then execute it. -useb denotes -UseBasicParsing, which was not found in the MS documentation, I got it from reddit.

Create an app on fly

You can create an app in fly for your local source code by running the command flyctl launch. This command will scan the source directory and create dockerfile and fly.toml. You should be logged in for its successful completion.

Deployment

I'm using some confidential keys, I got form podcastindex.org. So I had to set that in the environment variables. Fly.io helps us to set the envirionment vairables by setting the secrets. You can run the command flyctl secrets set KEY=VALUE to set secrets. Once set, you can use flyctl secrets list to view the list of secrets created.

Run the command flyctl deploy for deploying your application. This command will package your application as a docker container and will deploy in one of the machines. So far so good.

Trouble 1: Deployment succeeded but endpoints are not reachable. 🙄

I got over-excited and went to auto-pilot mode. I should've reviewed the dockerfile before deployment. In the dockerfile it was configured the CMD instruction as CMD [ "npm", "run", "start" ] and I haven't added any start script in my npm scripts. I added that and redeployed.

Trouble 2: PodcastIndex is returning unauthorized

We've set the api keys and secrets in environment variables. What could possible go wrong? 🤔

I added some logs and redeployed the app to monitor the secrets set in production. I noticed that the secret value in production is different from the actual. This issue was due to the symbol $ in the secret string. When i ran the command flyctl secrets set KEY=xxxx$xxxx, $ was getting replaced with the word flyctl. So in production it was coming as xxxxflyctlxxxx. to fix this i had to escape the character $ using backtick (`). I reset the secret using backtick and it worked after redeployment.

Wrap up

All sunday I was sitting in front of the monitor. I'm feeling bit tired and sleepy now. It was so tiresome even though it looked so simple. Definitely not a good way to spend your weekend.