The Vibe Coder’s Guide to Deployment Technically.dev published the fourth installment of its six-part "Software Engineering for Vibe Coders" series, a guide explaining what happens when AI-built apps move from localhost to production, sponsored by deployment platform Railway. The post walks through core deployment concepts including servers, the cloud, PaaS platforms that build and run code from a Git repo, build time versus runtime, and rollbacks, following fictional character Art Vandelay's potato chip import/export app. The series argues that a poorly run deployment pipeline can bring down an entire app, so vibe coders should understand the mechanics their coding agents handle under the hood. Lots of you are probably building apps with AI, and we want to do our part to make sure those apps can thrive when they make contact with real users. This 6-part series, Software Engineering for Vibe Coders , covers Art Vandelay’s sisyphean journey to ship an app to manage Vandelay Industries’ potato chip import & export business. Thanks to our friends at Railway https://railway.com/?utm medium=sponsor&utm campaign=technically , who help you peacefully deploy those vibe coded apps, for sponsoring this series. Spin up anything your vibe coded app might need at railway.com/new https://railway.com/new?utm medium=sponsor&utm campaign=technically . ICYMI, check out: The TL;DR Deployment is the moment your app leaves your laptop and moves onto the actual internet, where other people can use it. A graduation, if you will. - A server https://technically.dev/universe/server is a computer whose whole job is being always on, like many have confessed to their therapists. - The cloud https://technically.dev/universe/cloud industry, of which you’ve likely heard of, makes its money off buying giant servers and renting them piecemeal to people like us. - You probably don’t configure servers by hand anymore: a PaaS https://technically.dev/universe/paas like Railway builds and runs your code straight from your Git repo. - A deploy happens in two phases, at build time and runtime https://technically.dev/universe/runtime , and a bad deploy gets fixed with a rollback . Your coding agent can deploy an app in a few minutes, but what is it actually doing under the hood? This post covers what’s actually happening when it does, and how to keep deployments running smoothly when real users are depending on you. A poorly run deployment pipeline can bring down your whole app and does all the time , so deploy responsibly friends. Previously, at Vandelay Industries Art Vandelay is building an app that runs Vandelay Industries’s potato chip import/export empire. Over the last three posts, the app picked up a frontend https://technically.dev/universe/frontend and a backend https://technically.dev/universe/backend that talk through an API https://technically.dev/universe/api Part 1 https://technically.dev/posts/software-eng-vibe-coders-frontends-backends , a Postgres database https://technically.dev/universe/database full of supplier applications Part 2 https://technically.dev/posts/databases-for-vibe-coders , and auth that keeps Newman from stealing all the data Part 3 https://technically.dev/posts/security-for-vibe-coders . All of it works beautifully on Art’s laptop, what we call local development. When a friend “from the biz” asked to check out the app, all Art had to offer was localhost:3000, the address where he accessed the app on his local machine. Your laptop is not the internet localhost literally means “this computer, right here.” For other people to use the app, it has to run on a computer that isn’t Art’s laptop. That computer is called a server , and its one defining virtue is that it’s always on: it doesn’t close its lid, it doesn’t drop off the coffee shop Wi-Fi. It sits in the cloud, in a data center waiting to run your app for whichever authorized user requests it. 🚨 Confusion Alert “Host” and “server” get used interchangeably, and it mostly doesn’t matter. A host is any device on a network your phone counts , while a server is a host whose job is serving data to other devices. All servers are hosts; not all hosts are servers. I regret writing this alert. Getting off the laptop “The cloud” just means renting computers instead of buying them https://technically.dev/posts/whats-cloud . There are tons of options for deploying your app to the cloud, and the real question is how much you want to setup and how much you want to manage: IaaS https://technically.dev/universe/iaas Infrastructure as a Service is like renting an empty plot of land. Amazon’s EC2 is the classic example: you get a bare computer in a data center, and everything else the operating system https://technically.dev/universe/operating-system , the web server, a word called “nginx” you’ll learn against your will is your problem. PaaS Platform as a Service is renting an unfurnished apartment: the foundation is poured, the plumbing works, and you just move your stuff in. You point the platform at your code, and it handles the servers, networking https://technically.dev/universe/networking , and deploys. Heroku pioneered the category https://technically.dev/posts/the-details-platform-as-a-service ; Railway https://railway.com/?utm medium=sponsor&utm campaign=technically , where the app’s Postgres database from Part 2 already lives, is a more “modern” PaaS. Art is smart, and certainly doesn’t want to start from scratch. So all he’s going to do is connect the GitHub repo containing his app to Railway, let Railway pull and build the code, and get back a deployed URL that works from anywhere. The whole thing takes a few minutes, truly one of the modern marvels of app development. This shit rocks. This deployment pattern – where any recorded change to your app automatically triggers a new version for your users – is called continuous deployment. The PaaS watches your repo, and when you merge https://technically.dev/posts/whats-version-control-and-github a pull request https://technically.dev/universe/pull-request to your main production branch https://technically.dev/universe/branch , it deploys whatever’s in the repo. So it better be good. 🔍 Deeper Look PaaS isn’t strictly better than IaaS — you’re paying somewhat more and giving up fine-grained control, in exchange for skipping a bunch of setup. Everything is a tradeoff, and Art would be lucky to have the problem of needing to decide to scale from PaaS - IaaS. The stuff that can’t come with you: environment variables There’s one catch in the move from laptop to cloud, and it is always mildly tedious. Even trained software engineers have been known to fall prey to a foible here. The catch is that some of your app’s settings are different depending on where it runs . On the laptop, the app talks to a local test database, so it’s easy for you to prototype changes; in production though, it needs to connect to the production database https://technically.dev/universe/production-database . In our case that’s a Postgres instance on Railway, which has a completely different location and different address and password from the local version. The same goes for the Clerk secret key from Part 3 https://technically.dev/posts/security-for-vibe-coders – the Auth environment locally is not the same one your users are getting. Luckily, switching between these actual pieces of infrastructure is as simple as swapping in the right keys from your providers like Railway. However, none of these values can simply be checked into your Git repo for security , so secrets instead live in a special file called .env on your laptop, and in Railway’s Variables tab in production. You heard it here first, you will inevitably run into at least one problem related to this file and this tab. Having your first deploy be broken due to missing or incorrect environment variables is a right of passage, like Art Vandelay cutting his broker’s ties after their first deal closes. What actually happens when you push You have undoubtedly gotten a notification before telling you that your deploy failed lame . A deploy happens in two phases, and knowing which one failed saves a lot of time staring at logs. The build phase takes your raw code and makes it runnable: installing the software packages your app depends on, compiling the app, bundling the frontend into the files that the browser actually loads. These specifics are a bit obscure, but you can think of this as taking your messy app and tidying it up into a nice format for the server and your users. Here, a few things can go wrong. A typo might stop the code from compiling, which breaks the build. Your coding agent in theory should’ve caught an error like this before committing to your repo, but we all make mistakes. The good thing is that broken builds don’t actually go live, so it’s unlikely a user would run into a problem with this broken build. Runtime , on the other hand, is everything after a deployment is er, deployed: it’s the live app running on the server. Runtime errors are very unpleasant. They mean that the app built perfectly fine, but there’s something wrong with the running code itself. To fix your runtime errors, you will want to read through the logs that your server has emitted about what’s going on. It might be tempting to have your coding agent do this for you, and it can certainly help - but with error logs, you build an intuition over time with what the issue might be, and the only way to build that intuition is to actually look at the errors. Sorry. The good news is that logs are pretty human readable. Whichever deployment platform you’re using will display them to you – the good and the bad – and you can just read through them to see what happened. The actual error messages in the logs might be completely inscrutable, but pasting them into your agent s to explain them can help you build that ever-important intuition. How to not break prod Vibe coding is a serious endeavor. The fear that stops new builders from ever hitting deploy is that there’s the slightest chance the app with go down for actual users. The thing is, it will happen eventually failure comes for everyone , but like in life it’s all about how you recover. Every deploy is a snapshot – think of this like a point-in-time picture of your whole app – and your hosting platform saves them for you. So when Art’s “small tweak” takes out the supplier applications page on Monday morning, he doesn’t have to frantically have his coding agent get to work. He just clicks to revert to the previous deploy, and the platform swaps the live app back to the prior, working, version, usually pretty quickly. Nothing to fear my friends. Version control https://technically.dev/universe/version-control helps here too. You can always undo a commit in Git, and roll your production branch back to a working state, which is another way to trigger a working deploy. What breaks when the suppliers show up Real apps obviously aren’t deployed just once. Art will be tokenmaxxing from the Saint Frank, pushing new features all the time. A couple things that he’ll need to watch out for: Code and schema https://technically.dev/universe/schema don’t land at the same instant. A new feature often means new code and a database migration https://technically.dev/universe/migration Part 2 https://technically.dev/posts/databases-for-vibe-coders , and for a brief moment during the deploy, old code can be running against the new schema. The workaround is to make schema changes additive: add the new column while the old one keeps working, ship the code that uses it, and remove the old column in a later deploy once nothing depends on it. Don’t learn this the hard way by renaming a column in one shot on a live app. Catching problems before users do. Building with a coding agent means you’re likely shipping far more changes than a human used to, which is exactly what CI https://technically.dev/posts/the-details-ci continuous integration was built for. CI which coding agents are great at setting up runs automated checks on every commit does the app build, do tests pass . It won’t help much with frontend bugs, but browser use tools like Playwright can help and LLMs https://technically.dev/universe/llm are great at using them. One step further is a staging environment https://technically.dev/posts/whats-cicd , a full copy of the app that mimics production, where changes including those database migrations can land first and break harmlessly. Do all of that, and shipping might someday stop being scary. Jk, it will always be scary. Sorry. Where that leaves Art and you This is now a fully assembled app and actually live on the internet: a frontend suppliers can see, a backend holding it together, a database that remembers every application, auth deciding who gets in, and a server that’s always awake at a real address. The app isn’t on a laptop anymore. It runs while Art sleeps, waiting for suppliers, buyers, and the occasional Newman who is absolutely not getting in. And the best part is, Art never had to learn what nginx is. One question remains, and it’s the subject of the next post: when something breaks at 3am and something eventually will , how does Art find out before the suppliers do? Announcing Technically’s first live workshop https://technically.dev/workshops/personal-operating-system Sung Won Chung https://www.linkedin.com/in/sungwonchung1/ is a startup operator you should know. His superpower is building outsized influence within a startup, despite lacking a formal leadership title. On Oct 1st at 12pm PT, he’ll join us for 90 minutes to break down the system he’s used to become a “super IC” at startups like dbt Labs. You’ll learn to build your own personal + confidential operating system, and leave inspired to grow your influence beyond the title printed on your LinkedIn.