Today, I was working on CICD pipeline automation. But before I describe what I did, I want to describe the situation I was in. So first of all, I had these three deploy-able link which serve the purpose of following:
- preview.<domain> : auto-deploy upon PR into main (feature branch into main, that is)
- staging.<domain>: auto-deploy upon PR into release
- <domain>: this is what user sees, auto-deploy upon merge from main to release.
For preview, I noticed when I have multiple PR into main, only the last PR was reflected. So instead of seeing the fully rendered page on deployed link for each PR, I could only see the last one.
This was rather inconvenient in terms of developer experience.
So for the last two days, I was working on pipeline code and nginx config to fix this issue.
My goal was to have a deployable link that goes like <pr#>.<domain>.
Since our server is running on the local machine with cloudflared tunnel (tldr: it’s a reverse proxy that allow us to have connection with client without actually establishing connection with them ), I needed to configured few things.
First, I added DNS record CNAME so that any 1 level below subdomain will point to my cloudflared tunnel.
Second, I mapped Cloudflared Tunnel so that each request get mapped to appropriate localhost:PORT. For example, if client comes from <domain>, then they get mapped to localhost:3000 because that’s where I’m running my container. Likewise, for any subdomain 1 level below the apex (*.<domain>), it goes to localhost:80 (you might be wondering like ‘ok then how are we gonna serve unique link per pr then?’ -> we’ll get there shortly).
Third, to accommodate for unique link per pr, I made a ansible playbook that automatically generate Nginx mapping file whenever triggered by GitHub workflow.
After which, I had to make workflow for cleaning up annnnnd it took me more time than I expected. Basically, what happend was, in ansible, there was a community module for removing docker image. And my docker image’s name consist with pr-<pr#>:<some_increment>-<some_other_increment>. I didn’t realize that the name had to match, so I for the next few hours I tried my best to find a solution for this without making ansible playbook use shell scrpit ( at that point, it becomes much harder to maintain, mainly because of poor readability of shell script. ). Buut at the end, I ended up just using docker_image_info module and just loop through the every image:tag, and delete the image with matching name. And no, I did not use shell script for this, ansible has built-in module for looping.
I’m happy with the result, it works like a charm. But I’m kinda sad this delayed my side project, but then I’m happy with the learning, mixed feeling I guess.
Leave a comment