Build the mental model
When people say an application is deployed, they mean it has moved from a single developer's machine to a place where real users can reach it over the internet.
Write code
You write and test it freely on your own machine.
Build
A build step compiles, bundles, and optimizes it into a runnable form.
Deploy
The built result gets pushed onto a server or cloud platform.
Point a domain
A domain name is pointed at that server.
Users load it
Users type the domain into a browser and load the app.
A common beginner misconception is that deployment just means uploading files to a server, like copying a photo to a USB drive. In reality it involves a build process, environment configuration, and a live system that must keep working after you walk away from your keyboard.
- Development -- your own machine, safe to experiment freely
- Staging -- a private copy of production, for testing before release
- Production -- the live system real users actually depend on
This lesson is the map for the rest of this course. Later lessons, and the site's deep-dive tutorials on Docker, Kubernetes, Terraform, AWS, and CI/CD, each zoom into one piece of this bigger picture in real depth.
- Deployment
- The process of building your code and publishing it to a live server or cloud platform that real users can reach.
- Production
- The live environment real users actually use -- where uptime, correctness, and security genuinely matter.
- Staging
- A private copy of production used to test changes before they reach real users.
FROM CODE TO USERS
------------------
[ Your Code ]
|
v
[ Build ] (compile, bundle, optimize)
|
v
[ Deploy ] (push to a server or cloud platform)
|
v
[ Server / Cloud ]
|
v
[ Domain ] (thutatech.com)
|
v
[ Users ]Connect it to a real scenario
Real projects rarely hardcode one URL or one setting. Instead, they define a small config for each environment, development, staging, and production, and let the running app pick the right one. The example below is a simplified version of that pattern: a plain object with one entry per environment, each holding the URL that environment points to and whether debug logging should be on.
Development and staging keep debug logging on, since you want visibility while testing. Production turns it off, since verbose logs can leak information and slow things down in front of real users.
Looping over the object and printing each environment's settings is a stand-in for what a real app does at startup: it reads which environment it is running in, looks up the matching config, and configures itself accordingly. This is the same idea you will meet again, in more mechanical form, in the deep-dive tutorials on this site: Docker images, Terraform variables, and CI/CD pipelines all exist partly to make sure the right configuration reaches the right environment automatically, instead of a person manually editing settings by hand before each deploy.
Try the working example
const environments = {
development: { url: "http://localhost:3000", debug: true },
staging: { url: "https://staging.thutatech.com", debug: true },
production: { url: "https://thutatech.com", debug: false }
};
for (const [name, config] of Object.entries(environments)) {
console.log(`${name}: ${config.url} (debug: ${config.debug})`);
}development: http://localhost:3000 (debug: true)
staging: https://staging.thutatech.com (debug: true)
production: https://thutatech.com (debug: false)5-minute try-it
Copy the environments object for a project of your own (real or hypothetical) and add one more field: apiTimeoutMs, kept short for production and longer for development. Run the loop again and see how the output changes.
One important caution
Thinking deployment is just uploading files, ignoring the build step, configuration, and ongoing operation it actually requires
Using the same configuration for development, staging, and production without distinguishing between them
Wikipedia: Deployment environment — Cloud & Deployment