One of the most valuable parts of building FlashSeat was not implementing new features. It was debugging the problems that appeared when I moved the application from my local machine to AWS.
Before this project, I understood the basic responsibilities of a frontend, backend, and database. However, deploying an application made me realize how many additional components must work together.
The Architecture
FlashSeat uses a React frontend hosted on AWS Amplify, an Express API running in Docker on Amazon EC2, and a PostgreSQL database hosted on Amazon RDS.
Caddy acts as a reverse proxy and handles HTTPS.
Although each component worked individually during development, connecting them in production introduced several challenges.
Problem 1: Database Connectivity
One of the first significant problems involved connecting the backend to Amazon RDS.
The application could not successfully establish a database connection.
I had to investigate several possible causes, including the database endpoint, DNS resolution, environment variables, and AWS security group configuration.
Eventually, I resolved the connectivity problems by correcting the configuration and verifying that the EC2 instance could communicate with RDS.
This experience taught me the importance of understanding networking instead of treating cloud services as black boxes.
Problem 2: Missing Database Tables
After establishing connectivity, I encountered another issue: the application expected database tables that did not yet exist.
The production database was separate from my local development database, so the required schema had to be initialized.
I applied the SQL migration to create the necessary tables and verified that the API could query them successfully.
This reinforced an important principle: deploying application code does not automatically deploy the database schema it depends on.
Problem 3: Frontend and Backend Configuration
Another challenge involved communication between the Amplify frontend and the EC2 backend.
I needed to configure the frontend’s API URL correctly and ensure that the backend’s CORS configuration allowed requests from the deployed frontend.
The application also needed HTTPS to communicate securely.
Troubleshooting these issues helped me understand the differences between local development environments and production configurations.
My Biggest Takeaway
The most important skill I practiced was systematic debugging.
Instead of randomly changing configuration files, I learned to isolate each layer:
- Is the application running?
- Can the server resolve and reach the database?
- Does the database schema exist?
- Is the API returning the expected response?
- Can the browser communicate with the API?
Each question narrows down the possible causes of failure.
This project made me appreciate why backend engineers benefit from understanding Linux, networking, databases, and cloud infrastructure.
Writing code is important, but knowing how to diagnose problems across an entire system is equally valuable.