When people talk about web development, deployment usually gets one sentence.
"Push to production."
I don't think I'll ever say that again.
A few months ago, I rebuilt my college's website using Next.js and Sanity CMS. Development was exactly what I expected. I designed the pages, built the components, connected the CMS, migrated the content, and everything worked. The project felt like it was wrapping up.
Then came deployment.
The hosting provider wasn't running a VPS or a cloud platform. Everything had to run on a shared hosting environment. I assumed I'd upload the project, install Node.js, start the server, and call it a day.
The first startup failed immediately.
It turned out the server was running an old Node.js runtime that couldn't even understand the JavaScript syntax used by modern versions of Next.js. At first I thought the application was broken. After enough debugging, it became obvious the infrastructure was the real bottleneck.
That discovery started a chain of events I wasn't expecting. The hosting platform itself had to be upgraded before the website could even run. While that was happening, I spent more time learning about Linux, reverse proxies, hosting panels and deployment pipelines than I had during the entire development phase.
Once the migration was complete, I finally had access to a modern Node.js environment. I thought that would be the end of it.
It wasn't.
The production website was already serving users, so I couldn't simply replace it with my application. Everything had to be tested on a separate development subdomain while the existing website continued running without interruption.
That meant figuring out how Apache was serving requests, where the Node.js application was listening, and how to proxy only the development subdomain to the new server instance. The production domain had to continue serving the old website while dev.sreyas.ac.in quietly pointed to the new application.
There wasn't really a guide for this setup. It became a process of reading logs, testing configurations, breaking things, fixing them, and slowly understanding how every piece fit together.
Eventually the application started.
Then it crashed again.
This time the problem wasn't the server. It was the standalone build generated by Next.js. A couple of runtime packages weren't copied into the deployment bundle, so the application failed before it could finish starting. The fix was surprisingly simple once I found it. I manually copied the missing packages, restarted the server, and watched the website finally come online.
That moment felt different.
Not because the deployment was particularly complicated, but because I realised how different real deployments are from the ones we usually see in tutorials. Most examples assume modern cloud infrastructure where everything is already configured for you. Shared hosting expects something entirely different, and getting the two to work together meant understanding far more than just JavaScript.
By the end of the project I wasn't just thinking about React components anymore. I was thinking about runtime environments, process managers, reverse proxies, hosting limitations, deployment strategies and how to keep production running while testing new releases.
The website eventually came online without affecting the existing production site. Looking back, building the application taught me how to write software. Deploying it taught me how software actually reaches people.
Those turned out to be two very different skills.