How Deployment Works: The Steps That Take Code From Build to Live

Deployment isn't one magic button — it's a sequence of steps that turns your source code into a running app on a server. Learn the universal stages (build, transfer, install, migrate, switch, verify), what each one does, and how the modern automated pipeline runs them for you.

Published October 25, 202612 min readBy ACY Partner Indonesia
How deployment works — code moving through build, transfer, switch, and verify stages
300 × 250Ad Space AvailablePlace your ad here

You know what deployment is — taking your code and putting it somewhere real people can reach it. But when you watch it happen for the first time, it can feel like a black box: you run one command, wait a bit, and your changes magically appear on a live website. So what’s actually going on inside that pause? It turns out deployment isn’t one mysterious leap. It’s a sequence of small, sensible steps, and once you can name them, the whole thing stops being scary.

Here’s the reassuring part: those steps are nearly always the same, no matter what tool or platform you use. A push-button cloud service and a hand-typed deploy on a bare server both walk through the same logical stages — they just hide more or less of it from you. Learn the stages once and you’ll recognize them everywhere.

Deployment is a pipeline, not a moment

It’s tempting to picture deployment as a single instant: code is “here” one second and “live” the next. A more accurate picture is a pipeline — a line of steps your code flows through, each one finishing before the next begins. Some steps prepare the code, some move it, some get the server ready, and the last few flip the switch and make sure nothing’s on fire.

Thinking in stages matters for a practical reason: when a deployment fails, it fails at one specific stage. The build broke, or the files didn’t transfer, or the database migration errored out. If you know the stages, a scary “deployment failed” message becomes a much smaller question — which step? — and that’s almost always answerable.

If you haven’t yet, it helps to be clear on the gap deployment is crossing in the first place: the difference between code running on your machine and code running for everyone is covered in localhost vs production. Deployment is the bridge between those two worlds, and the stages below are the planks of that bridge.

The universal stages

Almost every deployment, from the simplest to the most elaborate, works through some version of these stages. Not every project uses all of them, but this is the full menu.

  SOURCE         BUILD          PACKAGE        TRANSFER
  ───────  ──►  ────────  ──►  ─────────  ──►  ─────────
  your code     compile /      bundle it      send to the
  + assets      bundle         up neatly      server




  VERIFY    ◄──  SWITCH    ◄──  MIGRATE   ◄──  INSTALL
  ────────       ───────       ─────────      ──────────
  is it up       point traffic  update the     install deps,
  and healthy?   at the new     database       set up runtime
                 version        if needed

Let’s walk through each one in plain language.

1. Build: turn source into something runnable

The code you write isn’t always the code that runs. Building is the step that transforms your human-friendly source into the form the server actually executes. What this means depends on your stack: a frontend project might bundle dozens of files into a few optimized ones, a TypeScript project compiles down to JavaScript, a compiled language turns source into a binary. Even a “no build needed” project conceptually has an empty build step.

The important idea: building happens before anything goes near the server, and it can fail. A typo that the server would never even see can stop a deploy dead here — which is exactly what you want. Catching problems at build time is far cheaper than catching them live.

# A typical build step for a web project
npm install        # get the libraries the code depends on
npm run build      # produce the optimized, runnable output

2. Package: bundle the result neatly

Once you have built output, you usually gather it into one tidy unit — sometimes called an artifact. This might be a zip file, a compiled binary, or a container image. The goal is a single, self-contained thing you can move around and trust: this exact bundle is what will run, nothing more, nothing less.

Packaging is what makes deployments repeatable. If you build once and deploy the same artifact to staging and then production, you know the thing you tested is the thing that went live. Building separately for each environment invites the classic “but it worked in staging” mystery.

3. Transfer: get it onto the server

Now the bundle has to physically travel from wherever it was built (your laptop, or a build server) to the machine that will run it. Under the hood this is just copying files across a network — securely. The most universal way is over an encrypted connection.

# Copy a built bundle to a server over a secure connection
scp app.tar.gz user@your-server:/var/www/app/

You don’t always type this yourself. A platform might pull your code from a repository, or a build server might push the artifact for you. But conceptually, something always crosses the gap from “where it was built” to “where it will run.”

4. Install: prepare the runtime on the server

Code rarely runs alone. It needs its dependencies — the libraries it imports — and a runtime to execute it (a language interpreter, a virtual machine, and so on). The install stage makes sure the server has all of that in place and at the right versions. On the server, this often looks similar to what you ran locally, just aimed at the production machine.

This is also where servers and laptops diverge in ways that bite people. The version of a tool on your machine might differ from the one on the server; a library that’s “obviously installed” locally might be missing in production. Installing dependencies explicitly, from a locked list, is how teams keep the two in sync.

5. Migrate: bring the database up to date

If your app uses a database, the new code might expect a new shape of data — a new column, a new table, a renamed field. A database migration is a small, ordered script that makes those structural changes so the database matches what the new code expects. Migrations run as part of the deploy, before the new code starts handling real traffic.

Migrations are the riskiest step — treat them with respect

Most deployment steps are safe to undo: if the new code misbehaves, you put the old code back. Database changes are different. Drop a column and the data in it is gone — rolling back the code won’t bring it back. That’s why careful teams write migrations to be additive when possible (add the new column, fill it, switch over, remove the old one later in a separate deploy), and always back up before a risky change. When a deployment goes badly wrong, it’s usually the migration, not the code.

6. Switch: point traffic at the new version

Up to now, the old version of your app has been quietly serving users the whole time. The switch is the moment the server starts using the new version instead. How abrupt this is depends on your setup. The simplest approach stops the old version and starts the new one — quick, but there’s a blink where the app is down. More careful setups start the new version alongside the old, confirm it’s healthy, and only then redirect traffic to it, so users never see an interruption.

   BEFORE SWITCH            AFTER SWITCH
   ─────────────            ────────────
   traffic ──► v1 (old)     traffic ──► v2 (new)
               v2 (warming) v1 (kept briefly,
                              then shut down)

That second pattern — start new, prove it works, then flip — is the heart of what people mean by “zero-downtime” deploys. The old version is often kept running for a few minutes so you can flip back fast if the new one misbehaves.

7. Verify: confirm it actually works

Deploying isn’t done when the new version starts — it’s done when you’ve confirmed it’s healthy. Verification can be as simple as opening the site and clicking around, or as automated as a health check: the server (or a monitoring tool) hits a special URL that answers “yes, I’m alive and working.” If that check fails, a good pipeline can automatically roll back to the last known-good version instead of leaving a broken app live.

# A health check is often just a tiny endpoint that returns "OK"
curl https://your-app.example.com/health
# → {"status":"ok"}

Skipping verification is how a “successful” deploy quietly takes a site down for an hour before anyone notices. The deploy ran; nobody checked. Always close the loop.

A worked example, start to finish

Let’s tie it together with a concrete-but-generic story. The team at ACY Partner Indonesia has a web app and Jane Doe just finished a feature. Here’s what happens when she deploys it.

1. BUILD     Jane's code is compiled and bundled into optimized files.
             A leftover typo would fail here — it doesn't. ✓

2. PACKAGE   The output is gathered into one artifact (app-v2.tar.gz).

3. TRANSFER  The artifact is copied to the production server over SSH.

4. INSTALL   On the server, dependencies are installed from the locked
             list, matching exactly what was tested.

5. MIGRATE   One small migration adds a "last_login" column. Backed up
             first, just in case.

6. SWITCH    The new version starts alongside the old. Once it answers
             healthy, traffic flips to it. The old version lingers 5 min.

7. VERIFY    A health check passes and Jane loads the site herself.
             Green across the board. The old version is shut down.

Notice what didn’t happen: nobody emailed files around, nobody edited code directly on the live server, and at no point was the app fully down with no fallback. That discipline — repeatable artifact, ordered steps, a way back — is what separates a calm deploy from a stressful one.

How automation runs these steps for you

Doing all of that by hand, every time, would be tedious and error-prone — and humans skip steps when they’re tired. So teams automate the pipeline. You connect your code repository to a system that watches for changes, and when you push new code, it runs the stages above automatically: build, test, package, deploy, verify. This is the idea behind CI/CD (continuous integration / continuous delivery).

   you push code


   ┌──────────────────────────────────────────┐
   │  AUTOMATED PIPELINE                        │
   │  build → test → package → deploy → verify  │
   └──────────────────────────────────────────┘


   live, or auto-rolled-back if a step fails

The crucial mental shift: automation doesn’t replace the stages, it runs the same stages reliably. Every concept above still applies. The pipeline is just a tireless assistant that performs the exact sequence the same way every time, refuses to continue if a step fails, and can undo its own work when verification doesn’t pass. That’s why “it works on my machine” matters less on a good pipeline — the machine that builds and tests is the same one every time, not your laptop.

The same stages hide inside one-click platforms

Modern hosting platforms can make deployment feel like a single button or a single git push. That’s a lovely experience, but it’s worth knowing it’s not magic — behind that button, the platform is running the very stages in this article. When something goes wrong, the platform’s logs will mention a build failing, an install erroring, a health check timing out. You already know what those words mean, so you’ll know where to look.

Rollbacks: the undo button

A pipeline that can deploy should also be able to un-deploy. A rollback is returning to the previous working version when a new one turns out to be broken. Because you packaged each version as its own artifact and kept the old one around, rolling back is often as quick as pointing traffic at the previous version again — the switch step, run in reverse.

This is exactly why the careful patterns earlier pay off. Keeping the old version alive for a few minutes, writing additive migrations, building immutable artifacts — none of that is busywork. It’s all in service of one calm sentence you want to be able to say when a deploy goes wrong: “no problem, roll it back.” A deployment process you can’t undo is a process that turns small mistakes into long outages.

Why understanding the stages helps you

You might be using a platform that handles all of this for you today, and that’s great. But understanding the stages still pays off constantly. When a deploy fails, you’ll read the error and immediately know it’s a build problem versus a migration problem versus a health-check problem — and that tells you where to fix it. When you choose tools, you’ll understand what they’re actually automating. And when you eventually deploy something the hard way, on a plain server, the steps won’t be a surprise, because you’ve seen the shape of them here.

Deployment stops being a black box the moment you can name what’s inside it. It’s not one leap — it’s build, package, transfer, install, migrate, switch, verify, with a rollback waiting in case you need it. Every tool you’ll ever use is some arrangement of those same ideas.

Wrapping up

Here’s the whole thing in one place:

  • Deployment is a pipeline, not a moment — code flows through ordered stages, and failures happen at one identifiable stage.
  • The universal stages are: build (source → runnable), package (one tidy artifact), transfer (move it to the server), install (dependencies + runtime), migrate (update the database), switch (point traffic at the new version), and verify (confirm it’s healthy).
  • Migrations are the riskiest stage because data changes can’t always be undone — back up and prefer additive changes.
  • Zero-downtime comes from starting the new version alongside the old, proving it healthy, then flipping traffic.
  • Automation (CI/CD) doesn’t replace these stages — it runs the same stages reliably every time, and can auto-rollback when a step fails.
  • A rollback is the undo button, and it only works if your process was built to allow it.

Next, it’s worth seeing how the stages differ depending on what you’re shipping — a folder of static files behaves very differently from a long-running server process, and knowing which one you have changes nearly every step above.

Tags:deploymentserverdevopsci-cdbeginner
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

SSL and encryption at rest — data protected in transit and on disk
Server / Server Security

SSL and Encryption at Rest: Protecting Data Both in Transit and on Disk

Encryption protects your data in two places: while it travels the network (in transit) and while it sits on disk (at rest). Learn the difference, why you need both, how TLS, full-disk encryption, and key management actually fit together, and the practical mistakes to avoid — explained from the.

Nov 9, 202613 min read
Securing ports and services — closing the doors on a server you don't use
Server / Server Security

Securing Ports and Services: Closing the Doors You Don't Use

Every open port on a server is a door someone could try to walk through. Learn what ports and services really are, why an exposed service is your biggest risk, and the simple discipline of closing everything you don't need — explained from the ground up.

Nov 8, 202611 min read
Principle of least privilege — granting only the minimum access each user and process needs
Server / Server Security

The Principle of Least Privilege: Give Everything Only the Access It Truly Needs

Least privilege is the quiet rule behind almost every solid security setup: every user, process, and key gets the minimum access required to do its job, and nothing more. Learn what it means, why it limits the blast radius of any breach, and how to apply it across users, services, files, and keys.

Nov 7, 202613 min read
Fail2ban and intrusion basics — watching logs and automatically banning repeated abusers
Server / Server Security

Fail2ban and Intrusion Basics: Automatically Banning the Bots Hammering Your Server

Attackers don't stop after one failed guess — they keep hammering, thousands of times a day. Learn how intrusion attempts actually look, what fail2ban does, how it watches your logs and bans abusers automatically, and how to set it up sensibly without locking yourself out — explained from zero.

Nov 6, 202613 min read
Keeping software updated — closing known security holes before attackers use them
Server / Server Security

Keeping Software Updated: The Boring Habit That Stops Most Server Breaches

Most servers don't get hacked through clever new attacks — they get hacked through old, known holes that a simple update would have closed. Learn why updates matter, what to update, how to do it safely without breaking things, and how to make it a habit instead of a panic.

Nov 5, 202610 min read
Firewall configuration — a default-deny rule set that opens only the ports you need
Server / Server Security

Firewall Configuration: Setting Up Default-Deny Rules Without Locking Yourself Out

Knowing what a firewall is and actually configuring one well are two different skills. Learn how to write a default-deny rule set, order rules correctly, allow your own access first, handle IPv6 and cloud security groups, and test before you commit — a practical, vendor-neutral guide from zero.

Nov 4, 202615 min read