Introduction
As a computer science student, I am always looking for projects that are not only technically challenging but also socially impactful. Voting is one of our most fundamental rights, yet the process—understanding timelines, checking eligibility, and navigating polling stations—can sometimes feel overwhelming.
That’s why I decided to build ElectionAssist: an interactive, responsive web application designed to demystify the election process. In this post, I want to walk you through what I built, the tools I used, and the deployment errors I had to conquer along the way.
What is ElectionAssist?
My goal was to build a UI that was clean, fast, and easy to understand. I focused on three core features:
The Interactive Timeline: A step-by-step visual tracker of the election cycle, from voter registration to counting day.
Voter Step-by-Step Guide: A wizard that acts as a checklist, helping users figure out their eligibility and how to cast their ballot.
Knowledge Flashcards: An interactive component with flippable cards to test users on general election trivia.
To prioritize speed and security, I designed the app to be completely client-side, ensuring no personal user data is ever stored. I used Google Antigravity as an agent-first IDE to help scaffold the frontend quickly and keep the codebase modular and efficient.
The Deployment Journey: Taking it to the Cloud
With the frontend looking good on my local PC, it was time to share it with the world. I decided to deploy the app using Google Cloud Run because of its scalability and ease of use with containerized applications.
I fired up my Cloud Shell and ran my deployment command:
Bash
gcloud run deploy election-assist \
--source . \
--port 8080 \
--allow-unauthenticated \
--region=us-central1
I expected a smooth deployment, but the cloud had other plans! Here are the two major roadblocks I hit and how I solved them.
Hurdle 1: The IAM Permission Denied Error
The first error I got looked like this:
PERMISSION_DENIED: Build failed because the default service account is missing required IAM permissions...
The Fix: Google Cloud uses a default service account to build your code in the background. My service account lacked the permission to save my files into Cloud Storage. I fixed this by granting the Storage Admin role to my compute service account using this command:
Bash
gcloud projects add-iam-policy-binding [MY_PROJECT_ID] \
--member="serviceAccount:[MY_SERVICE_ACCOUNT_EMAIL]" \
--role="roles/storage.admin"
Hurdle 2: Buildpack Exit Status 20 (Failed to Detect)
After fixing the permissions, the upload worked, but the build itself failed with:
step exited with non-zero status: 20
The Fix: Exit Status 20 means Google Cloud Buildpacks couldn't figure out what programming language or framework I was using. Since my app was purely static (HTML/CSS/JS), it lacked a package.json file. Cloud Run is designed to host web servers, not raw static files.
To solve this, I wrapped my static files in a lightweight Node.js web server called serve right from the terminal:
Bash
npm init -y && npm install serve && npm pkg set scripts.start="serve -s . -l 8080"
This generated a package.json file, telling Cloud Run exactly how to serve my app on port 8080.
The Result
After running the deploy command a third time... success!
Building and deploying new service... done
Seeing that green confirmation text in the terminal is one of the best feelings in software development. ElectionAssist is now live, secure, and accessible.
Final Thoughts
Building this project reinforced a crucial lesson: writing the code is only half the battle; deploying it and debugging infrastructure is where you truly level up as a developer. If you are building static sites and deploying to Cloud Run, don't forget your package.json!
Top comments (0)