🧰 A Beginner's Guide to NGINX and NGINX Proxy Manager

Arash AroraArash Arora
5 min read

Whether you’re self-hosting applications or deploying websites in production, reverse proxies are one of the most powerful tools in your DevOps toolbox. At the heart of it all is NGINX—a versatile, open-source server that can function as a web server, reverse proxy, load balancer, and even a mail proxy.

However, writing manual NGINX configurations—especially for multiple services, subdomains, and SSL certificates—can quickly become tedious, redundant and error-prone.

That’s where NGINX Proxy Manager (NPM) steps in to simplify everything with a clean and user-friendly interface.

In this blog, we’ll begin with the basics of NGINX, and then walk you through how to deploy NGINX Proxy Manager in just a few steps.


🧠 What is NGINX?

NGINX (pronounced engine-x) is a high-performance, open-source web server that’s designed for scalability and efficiency. It can be used for:

  • Serving static files (HTML, CSS, JavaScript)

  • Acting as a reverse proxy (routing external traffic to internal services)

  • Load balancing between servers

  • Caching for faster delivery

  • SSL termination (handling HTTPS connections)

Originally built to solve the C10K problem—handling 10,000+ concurrent connections—NGINX has become one of the most popular servers in the world.

🔄 What is a Reverse Proxy?

A reverse proxy acts as a gateway: it receives client requests, forwards them to the appropriate backend service, and returns the response to the client. This allows you to:

  • Host multiple apps on a single server (e.g., app1.example.com, app2.example.com)

  • Serve all apps over HTTPS using Let’s Encrypt

  • Hide internal infrastructure from the public

  • Apply rate limiting, access control, or logging policies

⚙️ Installing NGINX the Traditional Way

On most Linux distributions, you can install NGINX with:

sudo apt update -y
sudo apt install nginx -y

To verify NGINX is running:

systemctl status nginx

You should be able to visit http://<your-server-ip> and see the NGINX welcome page.

To configure new sites manually, you’ll edit files under /etc/nginx/sites-available/ and link them to /etc/nginx/sites-enabled/

😵‍💫 The Problem: Manual NGINX Config is a Pain

For each new service or domain, you have to:

  • Add a new subdomain

  • Set up SSL with Let’s Encrypt

  • Configure proxying rules

  • Handle authentication and security settings

  • Test your NGINX config and reload the service

This process is powerful but not beginner-friendly and quickly becomes a burden when managing many services.

🎉 The Solution: NGINX Proxy Manager (NPM)

NGINX Proxy Manager is a Docker-based application that wraps the power of NGINX in an easy-to-use web interface.

🔑 Key Features

  • Intuitive web UI to manage proxy hosts

  • Automatic SSL certificates via Let’s Encrypt

  • Redirection and 404 host handling

  • Access control via IP or basic auth

  • Custom NGINX config snippets

  • Lightweight and easy to deploy via Docker

🧱 How to Install NGINX Proxy Manager on Ubuntu/Debian

Prerequisites

  • A Linux server or cloud VPS

  • Docker and Docker Compose installed

  • A registered domain (optional but recommended)

Step 1: Install Docker & Docker Compose

sudo apt update
sudo apt install docker.io docker-compose -y

Verify Docker is running:

sudo systemctl status docker

If inactive, enable and start it:

sudo systemctl enable docker
sudo systemctl start docker

Step 2: Create the Docker Compose File

  • Create a working directory:

      mkdir npm && cd npm
    
  • Now create the docker-compose.yml file:

      version: '3.8'
      services:
        app:
          image: 'jc21/nginx-proxy-manager:latest'
          restart: unless-stopped
          ports:
            # These ports are in format <host-port>:<container-port>
            - '80:80' # Public HTTP Port
            - '443:443' # Public HTTPS Port
            - '81:81' # Admin Web Port
    
          environment:
            # Mysql/Maria connection parameters:
            DB_MYSQL_HOST: "db"
            DB_MYSQL_PORT: 3306
            DB_MYSQL_USER: "npm"
            DB_MYSQL_PASSWORD: "npm"
            DB_MYSQL_NAME: "npm"
          volumes:
            - ./data:/data
            - ./letsencrypt:/etc/letsencrypt
          depends_on:
            - db
    
        db:
          image: 'jc21/mariadb-aria:latest'
          restart: unless-stopped
          environment:
            MYSQL_ROOT_PASSWORD: 'npm'
            MYSQL_DATABASE: 'npm'
            MYSQL_USER: 'npm'
            MYSQL_PASSWORD: 'npm'
            MARIADB_AUTO_UPGRADE: '1'
          volumes:
            - ./mysql:/var/lib/mysql
    

💡 Why a database?
The database stores all your proxy host settings, SSL metadata, users, and configuration changes persistently

Step 3: Launch the Container

Run the containers:

docker-compose up -d

Step 4: Access the Web Interface

Open your browser and visit:
http://your-server-ip:81

Login with default credentials:

  • Email: admin@example.com

  • Password: changeme

You’ll be prompted to change your login details after the first login.

Once you login, you’ll be redirected to your dashboard

🔧 Setting Up Your First Proxy Host

  1. Go to "Proxy Hosts" > "Add Proxy Host"

  2. Enter your domain name (e.g., npm.domain.com)

  3. Enter the internal IP address and port of your service (e.g., 192.168.1.100:8080)

  4. Enable "Block Common Exploits"

  5. Switch to the SSL tab:

    • Enable SSL

    • Request a Let’s Encrypt certificate

    • Enable Force SSL

  1. Click Save

🎉 Done! Your service is now live, secure, and reachable via your custom domain. (npm.domain.com in this case)

🔐 Advanced Features

  • Access Lists – Restrict access using IP whitelisting or basic auth

  • Custom NGINX Directives – Add your own caching rules, headers, or security policies

  • Rate Limiting – Throttle excessive traffic and protect against DoS attacks

  • Redirection Hosts – Easily forward old URLs to new destinations

  • 404 Hosts – Define catch-all behavior for unknown or misrouted domains

💡 Common Use Cases

  • Host self-hosted apps like Nextcloud, Jellyfin, Bitwarden, or Portainer

  • Expose internal microservices on custom subdomains

  • Make local development tools publicly accessible with HTTPS

  • Replace complex manual NGINX or Traefik setups with a user-friendly dashboard

🧠 Final Thoughts

NGINX is incredibly powerful, but configuring it manually can be time-consuming and error-prone.
NGINX Proxy Manager simplifies this process without sacrificing flexibility.

It’s perfect for:

✅ Self-hosters
✅ Developers managing multiple projects
✅ Small teams hosting internal tools
✅ Anyone who wants easy SSL and quick proxy setup

0
Subscribe to my newsletter

Read articles from Arash Arora directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arash Arora
Arash Arora