learntodeploy / Learn / How to Deploy

How to Deploy an Application

A practical deployment guide — Last updated: September 2026

Software deployment is the process of taking working source code and making it available to users on a server. It is the step that turns a project on your machine into a service other people can reach. This guide walks through the standard deployment workflow — from a local project to a running production service — and explains what each step does and why it matters.

This is not a tutorial for any specific cloud provider or platform. The concepts here apply whether you are deploying to a virtual machine, a container platform, a platform-as-a-service, or a custom infrastructure. The goal is to understand the workflow well enough to recognize what is happening when a deployment fails — and to know how to fix it.

You can practice every step in this guide using the deployment simulator at LearnToDeploy. The simulator runs entirely in your browser — nothing is deployed to real servers, but the failure modes are real.

1. Build the Application

Before anything can be deployed, the source code has to become something that can run on a server. For a compiled language, that means compiling. For a interpreted language, it may mean installing dependencies and bundling assets. For a front-end application, it means producing static files.

A build is more than a transformation — it is a gate. A proper build catches problems before they reach users: syntax errors, missing dependencies, type mismatches, failing tests. The build step exists so that broken code fails here, not in production.

What the build step usually includes

The artifact is what gets deployed — not the source code. If the build produces different output depending on the machine it runs on, the deployment is not reproducible. Pin your dependency versions and build in a consistent environment.

2. Configure the Environment

An application rarely runs the same way in every environment. Development, staging, and production usually differ in database connections, API endpoints, ports, log levels, and secret keys. Environment configuration is how you make the same application behave correctly in each place without changing the code.

The standard approach is environment variables — key-value pairs injected at runtime. The application reads them when it starts and uses them to configure database connections, ports, feature flags, and secrets.

Common environment variables

Document every variable

A .env.example file listing every environment variable the application expects — with dummy values or comments explaining what each one does — is one of the most useful things a deployable project can include. It tells anyone setting up the environment exactly what they need.

# .env.example
PORT=8000
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=myapp
LOG_LEVEL=info
The most common deployment failure is a missing or wrong environment variable. The application starts, but it cannot connect to the database, or it listens on the wrong port, or it falls back to a default that does not match what the platform expects. Always compare the live environment against the documented example before deploying.

3. Configure Environment Variables

Setting environment variables correctly is its own step because it is where so many deployments fail. The variables need to be present in the environment where the application runs — not just on your local machine. On a platform, this usually means configuring them in the platform's dashboard, a secrets manager, or a deployment configuration file.

Things to get right

# Running the app with environment variables
PORT=8000 DATABASE_HOST=postgres DATABASE_PORT=5432 \
  LOG_LEVEL=info node server.js

4. Produce a Build Artifact

After the build step, you have something deployable — a compiled binary, a Docker image, a bundle of static files, or a directory of installed dependencies and source code. This artifact is what you ship. It should be the same artifact you tested, not a rebuild from different source.

Versioning the artifact matters. If you deploy myapp:latest and something goes wrong, you need to know what :latest was at that moment — and you need to be able to deploy the previous version. Tagging images and binaries with a version, a git commit hash, or a build number makes deployments traceable.

# Building a Docker image with a version tag
docker build -t myapp:1.2.0 .
docker tag myapp:1.2.0 myapp:latest

An artifact should be immutable — once built, it does not change. If you need to change something, you build a new artifact with a new version. This is what makes rollbacks possible: you do not rebuild the old version, you redeploy the one you already have.

5. Containerize (When Appropriate)

Docker containers package an application with its runtime, dependencies, and configuration into a single image that runs the same way on any machine with a container runtime. Containerization is not required for every deployment, but it is the standard for a reason: it eliminates the “it works on my machine” problem by making the deployment environment explicit and reproducible.

A basic Dockerfile

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]

What to get right in a Dockerfile

A Dockerfile that builds locally can still fail in production. The base image might be different, the startup command might not match what the platform expects, or the application might listen on a different port than the one the platform routes traffic to. The deployment simulator includes Docker projects where these exact problems appear.

6. Configure CI/CD

Continuous integration and continuous deployment (CI/CD) automate the path from source code to production. CI runs the build and tests on every change. CD takes the built artifact and deploys it — sometimes automatically, sometimes after a manual approval.

A typical CI/CD pipeline

CI/CD is not just about speed — it is about consistency. A manual deployment that depends on someone remembering every step is a deployment that will eventually go wrong. A pipeline that runs the same steps in the same order every time is a deployment you can trust.

The deployment simulator includes CI/CD tooling — a pipeline editor, build stages, and deployment logs — so you can practice configuring and debugging pipelines without a real CI system.

7. Deploy

Deployment is the act of making the artifact available to users. What this looks like depends on the platform: pushing a container image and restarting a service, uploading static files to a CDN, or triggering a platform to pull the latest image and roll it out.

A deployment is not successful when the command returns successfully. It is successful when the application is running and responding to requests. The deployment step should include a verification that the service is actually alive — usually a health check.

Deployment best practices

8. Monitor the Deployment

Once the deployment is live, monitoring tells you whether it is healthy. Monitoring is not just about alerts — it is about having enough visibility into the running service to notice problems before users do.

What to monitor

A deployment that you cannot monitor is a deployment you cannot operate. Make sure the service emits enough signal — health checks, structured logs, metrics — to understand its state.

9. Inspect Logs

When something goes wrong, logs are the first place to look. Logs record what the application and the platform did — startup, configuration, requests, errors, shutdown. Reading logs is a core debugging skill.

How to read logs effectively

A common mistake is to guess at the cause and redeploy without reading the logs. A redeploy that does not change anything will fail the same way. Read the logs first, form a hypothesis, then make a targeted fix.

10. Troubleshoot Failures

Deployment failures fall into a few common categories. Knowing the category tells you where to look.

Common deployment failures

The troubleshooting process is the same regardless of the specific failure: read the logs, check the configuration, verify the state of the running service, form a hypothesis, test it, and fix the root cause — not just the symptom.

11. Recover or Roll Back

When a deployment causes a problem, the fastest way to restore service is often to go back to the last known-good version. This is a rollback — redeploying the previous artifact rather than trying to fix the current one live.

When to roll back

When to fix forward

Either way, the goal is to restore service first and understand the problem second. A postmortem after the incident captures what happened, why, and what to do differently next time.

Practice Deployment with a Simulator

Reading about deployment is not the same as doing it. The LearnToDeploy deployment simulator lets you practice this entire workflow in a browser-based environment:

The simulator includes deployment failures planted in the projects — wrong ports, missing environment variables, broken Dockerfiles, failed health checks. Each one is a realistic problem that teaches you how to diagnose and fix it. Nothing is deployed to real infrastructure; everything is learned in the browser.

For a broader view of the concepts behind each step, see the deployment concepts library inside the app.

← Back to Learn