Build Log #4 - A simpler Application flow, eventually
May 13, 2025
🛠️ What I Worked On
A week of building, unbuilding, and rebuilding. I made a small but fixable mistake in the Database Modeling. Also a bunch of other small changes that I've forgotten since.
🏗 Applications & Containers
Ispent an evening building out the ability to deploy a Docker image directly to a server via the "New Container" button on its overview page. This felt like a good idea whilst building and testing it, but I quickly ran into issues with the implementation the next day.
To break it down, I have:
Applications
- Tied to a Github Repository
- Has Environment Variables
- Has Volumes, Labels to pass to Tugboat when creating, updating containers.
Containers
- A copy of the Docker Container instance on the server.
- Has a container ID
- Stores Container status from Tugboat's Heartbeats
This setup works for deploying a GitHub repository, but it doesn't work well if I want to deploy a database, queue or any other Docker image.
To remedy this, I spent an evening copy/pasting existing parts of the "Create Application" flow to add a "Create Container" flow and by the end of the evening I had a simple flow working.
Here's where the problem started (the next day).
Whilst finishing off adding missing bits from the Container flow, I realised that Containers would need Environment Variables, Labels and Volumes the same as Applications, and that these would need storing in the database for future deployments. The simple solution was to just add a "container_id" foreign key to those existing tables and call it a day, however the levels of duplication here didn't sit right with me.
Notable duplication
- About two-thirds of the Container and Application creation flows were identical, with the main difference being an extra step in Applications to connect GitHub.
- Background jobs to deploy Applications and Containers used a lot of the same functionality with a few changes to remove existing containers before creating news ones in the Container flow (compared to Application flow that uses Blue/Green deployment)
So I went back to the drawing board and figured out a much cleaner method of deploying both Docker Images and Github Repositories using the existing Application flow. I started by reorganizing a few inputs and conditionally hiding others depending on whether the Application type was Docker or GitHub. In the end, I managed to saved most of the existing work on the frontend as most of the big changes took place in the background jobs.
The mistake of hastily adding a new Container flow one evening, and consequently, the result of fixing it was well worth the effort. Now the Application flow supports both types, the impending doom of a load of duplicated code across the system has gone and the whole flow is a lot more robust. I can confidently say I trust the dance between Serversinc and Tugboat for deploying Containers now.
✅ Wins
- Simpler Application/Container flows; a reduction in duplication, more robust background jobs
- Tugboat now supports Volumes, Labels and Networks.
⚠️ Challenges
- Rebuilding the Application flow without rebuilding the whole wheel. - I didn't want to spend a couple of weeks rebuilding everything I'd done with the Application flow so I set myself the constraint of keeping as much existing code as possible unless there's a clear benefit to scrapping it.
💡 What I Learned
- The simplest paths aren't always the best path – It's common to hear engineers say "Whatever the most obvious fix is, just do that" but it's often worth stepping back to see the full picture before diving in.
🔜 Next Up
- Still working on Traefik, but maybe this week is the week!