Skip to content
C

Deployment & DevOps

Linux basics, production environment variables, Docker and Dockerfiles, Docker Compose, CI/CD with GitHub Actions, cloud deployment platforms (AWS/Azure/GCP) and options (VMs, PaaS, containers, serverless), Nginx as a reverse proxy, production configuration essentials, monitoring, and a beginner-friendly deployment path.


Writing an application is only half the journey — getting it running reliably on a real server, accessible to real users, is the other half. This file covers the essential deployment and DevOps concepts every developer should know, from basic Linux commands through Docker, CI/CD, and cloud deployment.


1. What is Deployment and DevOps?

What is it?

  • Deployment means taking your finished application and making it available for real users to actually use — typically on a server, rather than your own laptop.
  • DevOps (Development + Operations) is the broader set of practices and tools for building, testing, deploying, and monitoring applications reliably and repeatedly.
Definition: DevOps is a set of practices combining software development and IT operations, aiming to shorten the development lifecycle and deliver reliable software continuously.

2. Linux Basics

What is it?

Most servers run Linux, so basic command-line familiarity is essential for deployment work.

Essential Commands

bash
pwd # print current directory ls # list files in current directory ls -la # list files, including hidden ones, with details cd folder_name # change directory mkdir new_folder # create a new folder rm file.txt # delete a file rm -rf folder_name # delete a folder and everything inside it (be careful!) cat file.txt # display a file's contents grep "search_term" file.txt # search for text within a file chmod +x script.sh # make a file executable ps aux # list running processes kill <process_id> # stop a running process sudo command # run a command with administrator privileges

Common Mistakes

  • Using rm -rf carelessly — like shutil.rmtree() from the Automation file, this permanently deletes with no confirmation and no undo.
  • Forgetting sudo is required for commands needing administrator privileges (like installing system-wide software).

Important Points

  • Comfort with basic Linux commands is essential for working with servers, Docker containers, and most cloud deployment platforms.

3. Environment Variables in Production (Recap)

As covered in the Security file, sensitive configuration (database passwords, API keys, secret keys) should always be stored as environment variables — never hardcoded. In production, these are typically set directly on the server or cloud platform's configuration panel, rather than in a local .env file.

bash
export DATABASE_URL="postgresql://user:password@host:5432/dbname" export SECRET_KEY="your-production-secret-key"

Important Points

  • Production environment variables are usually configured through your hosting platform's dashboard or configuration files, not committed .env files.

4. Docker

What is it?

Docker packages an application together with everything it needs to run (code, dependencies, system libraries) into a single, portable container — ensuring it runs identically on any machine, eliminating the classic "it works on my machine" problem.

Definition: Docker is a platform for packaging an application and its dependencies into a lightweight, portable container that runs consistently across different environments.

Writing a Dockerfile

dockerfile
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000 CMD ["python", "app.py"]

Explanation of the Code

  • FROM python:3.12-slim starts from an existing, pre-built image containing Python already installed.
  • WORKDIR /app sets the working directory inside the container.
  • COPY requirements.txt . followed by RUN pip install ... installs dependencies before copying the rest of the code — this ordering lets Docker reuse this step from a cache if only your code (not dependencies) changed, speeding up rebuilds.
  • EXPOSE 5000 documents which port the application listens on.
  • CMD [...] specifies the command that runs when the container starts.

Building and Running a Docker Container

bash
docker build -t my-python-app . docker run -p 5000:5000 my-python-app

Explanation: docker build creates an image from the Dockerfile. docker run -p 5000:5000 starts a container from that image, mapping port 5000 on your machine to port 5000 inside the container.

Docker Compose — Running Multiple Services Together

yaml
# docker-compose.yml version: "3.9" services: web: build: . ports: - "5000:5000" environment: - DATABASE_URL=postgresql://user:password@db:5432/mydb depends_on: - db db: image: postgres:15 environment: - POSTGRES_PASSWORD=password
bash
docker-compose up

Explanation: Real applications often need multiple pieces working together (a web app and a database). Docker Compose defines and starts them all together with a single command, and depends_on ensures the database starts before the web application that needs it.

Common Mistakes

  • Forgetting to add a .dockerignore file (similar to .gitignore), accidentally including unnecessary files (like a local venv/ folder) in the container image, bloating it unnecessarily.
  • Hardcoding secrets directly in a Dockerfile instead of passing them as environment variables at runtime.

Important Points

  • Docker ensures consistency between development, testing, and production environments.
  • Docker Compose is the standard tool for running multi-service applications (e.g., a web app plus a database) together during development.

5. CI/CD (Continuous Integration / Continuous Deployment)

What is it?

  • Continuous Integration (CI) — automatically running tests (from the Testing file) every time code is pushed, catching bugs before they merge into the main codebase.
  • Continuous Deployment (CD) — automatically deploying code to production once it passes all checks, without manual, error-prone deployment steps.
Definition: CI/CD is a set of practices that automates testing and deployment, ensuring code changes are verified and delivered to production quickly and reliably.

Simple Example — GitHub Actions Workflow

File: `.github/workflows/test.yml`

yaml
name: Run Tests on: push: branches: [main] pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: pip install -r requirements.txt - name: Run tests run: pytest

Explanation of the Code

  • on: push / pull_request triggers this workflow automatically whenever code is pushed or a Pull Request is opened against main.
  • Each step runs one action: checking out the code, setting up Python, installing dependencies, and finally running the test suite (from the Testing file) with pytest.
  • If any step fails (especially the tests), GitHub marks the check as failed, visibly warning the team before broken code gets merged.

Real-World Example

A team's CI/CD pipeline might automatically run the full test suite on every Pull Request, then — if all tests pass and the PR is merged — automatically build a Docker image and deploy it to production, entirely without manual intervention.

Important Points

  • CI catches bugs early, before they reach main or production.
  • CD automates the actual deployment process, reducing manual errors and speeding up how quickly working code reaches users.

6. Cloud Deployment Platforms

What is it?

Cloud platforms provide the actual servers, storage, and infrastructure needed to run your application, without you needing to own or physically manage hardware.

The Major Providers

ProviderNotes
AWS (Amazon Web Services)The largest, most widely used cloud platform, with an enormous range of services
Azure (Microsoft)Popular in enterprises already using Microsoft's ecosystem
Google Cloud Platform (GCP)Strong in data analytics and machine learning services

Common Deployment Options (Conceptual)

ApproachDescription
Virtual Machines (e.g., AWS EC2)A full remote computer you configure and manage yourself
Platform-as-a-Service (e.g., AWS Elastic Beanstalk, Azure App Service)Upload your code; the platform handles servers, scaling, and infrastructure
Containers (e.g., AWS ECS, Google Cloud Run)Deploy your Docker container directly, with the platform managing the underlying infrastructure
Serverless (e.g., AWS Lambda)Deploy individual functions that run only when triggered, without managing a server at all

Important Points

  • Beginners typically start with a simpler Platform-as-a-Service option before managing raw virtual machines directly.
  • All three major cloud providers offer broadly similar core services, differing mainly in naming, pricing, and their surrounding ecosystems.

7. Nginx (Reverse Proxy)

What is it?

Nginx is a widely used web server, most commonly deployed in front of a Python application as a reverse proxy — receiving incoming web traffic and forwarding it to your actual application server.

Definition: A reverse proxy is a server that sits between clients and your application, forwarding requests and often handling tasks like load balancing, SSL encryption, and serving static files.

Simple Example — Basic Nginx Configuration

nginx
server { listen 80; server_name myapp.com; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; } }

Explanation

  • This configuration tells Nginx: "any request coming in on port 80 for myapp.com should be forwarded to the actual Python application running on port 5000."
  • In real production deployments, Nginx also commonly handles HTTPS/SSL, serving static files efficiently, and load-balancing traffic across multiple application instances.

Important Points

  • Development servers (like Flask's built-in server) aren't designed for production traffic — a reverse proxy like Nginx, paired with a proper production application server, is standard practice.

8. Production Configuration Essentials

Key Checklist

  • Turn off debug mode — Flask's debug=True (from the Web Development file) must never be enabled in production; it can expose sensitive internal details.
  • Use environment variables for all secrets — never hardcoded values (covered in the Security file).
  • Use a proper production server — e.g., gunicorn for Flask/Django, rather than the framework's built-in development server.
  • Enable proper logging — using the logging module (from the Debugging & Logging file), not print().
  • Set up HTTPS — encrypting traffic between users and your server.

Simple Example — Running with Gunicorn

bash
pip install gunicorn gunicorn app:app --bind 0.0.0.0:8000 --workers 4

Explanation: gunicorn is a production-grade WSGI server, far more robust and performant than Flask's built-in development server. --workers 4 runs 4 separate worker processes, allowing the application to handle multiple requests genuinely in parallel.


9. Monitoring

What is it?

Once deployed, monitoring tools continuously check that your application is running correctly, alerting you the moment something goes wrong — extending the error-tracking concept introduced in the Debugging & Logging file.

Key Practices

  • Uptime monitoring — automated tools that regularly check if your application is responding, alerting you immediately if it goes down.
  • Error tracking — tools (like Sentry, mentioned in the Debugging & Logging file) that automatically capture and report exceptions happening in production.
  • Performance monitoring — tracking response times and resource usage to catch performance degradation before it seriously affects users.

Important Points

  • Monitoring turns "a user complains something is broken" into "the team is alerted the instant something breaks" — a critical difference for professional, reliable software.

10. A Beginner-Friendly Deployment Path

For a first deployment, a reasonable, approachable path looks like:

  1. Develop and test your application locally, using a virtual environment (from the Environment & Package Management file).
  2. Write tests (from the Testing file) and set up a simple CI workflow (GitHub Actions) to run them automatically.
  3. Containerize the application with a Dockerfile.
  4. Deploy using a beginner-friendly Platform-as-a-Service option (many offer free tiers for learning projects) rather than manually configuring raw virtual machines.
  5. Set environment variables through the platform's dashboard (never hardcoded).
  6. Add basic logging and, once comfortable, an error-tracking tool.

Common Beginner Mistakes — Summary for This Section

  • Leaving debug mode enabled in a production deployment.
  • Hardcoding secrets instead of using environment variables in production configuration.
  • Using a framework's built-in development server for real production traffic.
  • Deploying without any automated tests or CI checks in place.
  • Skipping monitoring entirely, only finding out about outages when users complain.

Cheat Sheet — Deployment & DevOps

bash
# Linux basics ls -la; cd folder; mkdir folder; rm -rf folder; cat file; grep "term" file # Docker docker build -t app-name . docker run -p 5000:5000 app-name docker-compose up # Production server (instead of the framework's dev server) gunicorn app:app --bind 0.0.0.0:8000 --workers 4
yaml
# GitHub Actions CI (.github/workflows/test.yml) on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - run: pip install -r requirements.txt - run: pytest

Interview Questions

Q1. What is the difference between Continuous Integration and Continuous Deployment? Answer: Continuous Integration automatically runs tests whenever code changes are pushed, catching bugs early. Continuous Deployment automatically deploys code to production once it passes all checks, without manual intervention.

Q2. What problem does Docker solve? Answer: It packages an application with all its dependencies into a portable container, ensuring it runs identically across different environments (development, testing, production), eliminating "it works on my machine" issues.

Q3. Why shouldn't a framework's built-in development server (like Flask's) be used in production? Answer: Development servers aren't designed for production-level traffic, concurrency, or security — a proper production server (like Gunicorn), often paired with a reverse proxy (like Nginx), is standard practice.

Q4. What is a reverse proxy, and why is Nginx commonly used as one? Answer: A reverse proxy sits between incoming client requests and your actual application server, forwarding traffic and often handling tasks like HTTPS, load balancing, and serving static files. Nginx is a widely used, reliable choice for this role.

Q5. Why is monitoring important after deployment? Answer: It alerts the team immediately when something breaks in production (uptime issues, errors, performance degradation), rather than relying on users to notice and report problems.


Practice Questions

Beginner

  1. Write a basic Dockerfile for a simple Python script that prints "Hello, World!"
  2. Practice basic Linux commands: create a folder, create a file inside it, list its contents, then delete the folder.
  3. Write a simple GitHub Actions workflow that installs dependencies and runs pytest on every push.
  4. Explain, in your own words, the difference between a virtual machine and a serverless deployment.
  5. Set an environment variable in your terminal and access it from a Python script using os.environ.

Intermediate

  1. Containerize a simple Flask application with a Dockerfile, build the image, and run it locally.
  2. Write a docker-compose.yml file that runs a Flask app alongside a PostgreSQL database.
  3. Extend a GitHub Actions workflow to also check code style/linting before running tests.
  4. Write a basic Nginx configuration that proxies requests to a Python application running on port 8000.
  5. Explain, in your own words, the beginner-friendly deployment path outlined in this file, and identify which step you'd need to learn more about first.

Challenge

  1. Fully containerize the Blog Application mini project from the Web Development file, including a docker-compose.yml for the app and its database.
  2. Set up a complete CI pipeline (GitHub Actions) that runs tests on every Pull Request and blocks merging if tests fail.
  3. Research (and summarize in your own words) the tradeoffs between deploying to a Platform-as-a-Service versus a raw virtual machine versus a serverless function, for a small personal project versus a large production application.

Mock Test

  • Deployment & DevOps - Quick Test

    10 questions covering Linux basics, Docker, Docker Compose, CI/CD with GitHub Actions, cloud deployment options, Nginx, and monitoring.

    10 questions · 10 min · Easy
    Start Mock Test