금. 8월 8th, 2025

Hi! 🚀 Are you running a bunch of web services and tired of manually modifying Nginx configuration files, renewing SSL certificates, etc. every time? Worry no more! Today, we’re going to dive into how to install and utilize Nginx Proxy Manager (NPM) with Docker Compose, which makes all of this magically easy and intuitive.

—.

💡 1. What is Nginx Proxy Manager (NPM)?

Nginx Proxy Manager is, as the name suggests, a reverse proxy management tool based on Nginx. But it’s more than just a proxy – it offers a powerful set of features through a web-based, intuitive user interface (GUI), including

  • Reverse Proxy Settings: You can easily set up the ability to forward incoming requests from the outside to a specific server (e.g., web server, application server) inside. For example, you can direct requests coming in to blog.example.com to a Ghost blog running on port 192.168.1.100:2368 inside.
  • SSL Certificate Management (Let’s Encrypt Automation): One of the biggest benefits! Let’s Encrypt makes it easy to get free SSL/TLS certificates and renew them automatically. This is essential for securing your website and enabling HTTPS 🔒.
  • Custom Nginx Directives: For advanced users, you can add custom Nginx settings (e.g. caching, adding security headers) to specific proxy hosts.
  • Redirect and 404 page settings: You can redirect specific URLs to other URLs, or set up 404 error pages for pages that don’t exist.
  • Access Control (Basic Auth):** You can set up to require a username and password to access certain proxy hosts.

In a nutshell, NPM is a tool that allows you to do all the work of setting up Nginx and managing SSL certificates without complicated commands or editing configuration files using only a web browser.

🤔 2. Why should I use Nginx Proxy Manager?

If you’ve ever tried to set up Nginx yourself before, you’ve probably had to modify the nginx.conf file, enter the systemctl reload nginx command, and run the Let’s Encrypt certbot manually. This process has the following problems.

  • Complex configuration files:** Nginx configuration is grammatically challenging, and a single typo can break the service.
  • SSL certificate renewals:** Let’s Encrypt certificates need to be renewed every 90 days, and it’s easy to miss them if you manage them manually.
  • Managing multiple services:** If you run multiple web services (WordPress, Nextcloud, Home Assistant, etc.), managing the Nginx settings for each of them can be very cumbersome.

NPM solves these problems.

  • Intuitive GUI: Create proxy hosts and apply SSL with just a few clicks, without having to know complex Nginx syntax.
  • Automated SSL: Let’s Encrypt certificate issuance and renewal is fully automated, so you don’t have to worry about forgetting anything.
  • Centralized management: Manage reverse proxy settings for all your web services from a single NPM dashboard.
  • Save time: Spend less time on setup so you can focus on developing and running your core services.

🛠️ 3. Install NPM with Docker Compose

Nginx Proxy Manager is easiest to deploy in a Docker environment, especially with Docker Compose, which allows you to configure NPM and the required databases in one go with just a few lines of configuration.

For more information, see #### 3.1. What to bring

  • Install Docker and Docker Compose: Docker and Docker Compose must be installed on your server. If they are not, please refer to the official documentation to install them. (For example, sudo apt-get install docker.io docker-compose)
  • Domain: You will need a domain to connect to the service you want to proxy (e.g., your-app.com, blog.your-domain.com), and an A record or CNAME record configured in your DNS settings for this domain to point to the public IP of the server.

For more information, see: #### 3.2. Write the Docker Compose files

NPM requires a database (MariaDB or MySQL) to store configuration information, so the docker-compose.yml file defines two containers: an NPM container and a database container.

# docker-compose.yml
version: '3.8'

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    ports:
      # web traffic (HTTP).
      - '80:80'
      # secure web traffic (HTTPS)
      - '443:443'
      # NPM admin page (HTTP)
      - '81:81'
    environment:
      DB_MYSQL_HOST: db
      db_mysql_port: 3306
      DB_MYSQL_USER: 'npmuser'
      DB_MYSQL_PASSWORD: 'your_db_password' # Change to a strong password!
      DB_MYSQL_DATABASE: 'npm'
    volumes:
      # NPM settings and certificate data (persistent storage)
      - npm_data:/data
      - npm_letsencrypt:/etc/letsencrypt
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: 'jc21/mariadb-aria:latest' # or 'mysql:8.0'
    container_name: nginx-proxy-manager-db
    environment:
      MYSQL_ROOT_PASSWORD: 'your_root_password' # Change to a strong password!
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npmuser'
      MYSQL_PASSWORD: 'your_db_password' # Set the same as DB_MYSQL_PASSWORD in the app service
    volumes:
      # DB data (persistent storage)
      - npm_db:/var/lib/mysql
    restart: unless-stopped

volumes:
  npm_data:
  npm_letsencrypt:
  npm_db:

**🤔 What does each setting mean?

  • version: '3.8': Specifies the version of the Docker Compose file. It is recommended to use the latest version.
  • services: Defines the containers to run.
    • app (NPM container):
      • image: 'jc21/nginx-proxy-manager:latest': Use the official image of Nginx Proxy Manager.
      • container_name: nginx-proxy-manager: Specify a container name to make it easily identifiable.
      • ports:
        • 80:80: Connect external port 80 to port 80 of the container (HTTP).
        • 443:443: Connect external port 443 to port 443 in the container (HTTPS).
        • 81:81: Connect external port 81 to port 81 of the container (NPM management UI).
        • ⚠️ Important: Make sure that ports 80, 443, and 81 on your server are not in use by other services.
      • environment: Defines the database connection information. The DB_MYSQL_HOST uses the name of the db service.
      • volumes: Attach volumes for permanently storing data inside the container on the host machine. For example, npm_data stores NPM’s configuration files and logs, and npm_letsencrypt stores the Let’s Encrypt certificate file.
      • depends_on: - db: Specifies that the app container runs after the db container is started first.
      • restart: unless-stopped: Sets the container to restart automatically even if it is stopped.
    • db (Database Container):
      • image: 'jc21/mariadb-aria:latest': Use the MariaDB image. If you want MySQL, you can change this to mysql:8.0, etc.
      • container_name: nginx-proxy-manager-db: The name of the database container.
      • environment: Set the root password, database name, username, and user password for the database. Make sure to change them to strong passwords! (MYSQL_USER and MYSQL_PASSWORD must be the same as DB_MYSQL_USER and DB_MYSQL_PASSWORD in the app container).
      • volumes: - npm_db:/var/lib/mysql: The volume for permanently storing database data.
  • volumes: Defines the Named Volumes that will be used in the services section. Docker will create and manage them automatically.

For more information, see: #### 3.3. Run NPM

  1. Create the above docker-compose.yml file in the desired directory on your server (e.g. ~/npm).
  2. Navigate to that directory.
    cd ~/npm
  3. Run the container using Docker Compose.
    docker compose up -d

    The up creates and starts the container, and the -d option makes it run in the background.

If all goes well, you can verify that the containers are running well with the docker compose ps command.

docker compose ps

The output should show the status of the nginx-proxy-manager and nginx-proxy-manager-db containers as Up.

🌐 4. Setting up and utilizing Nginx Proxy Manager preferences

Once the container is successfully running, you can now access the NPM management page via a web browser to start setting it up.

4.1. Access the NPM management page

Open a web browser and connect using your server’s IP address and port 81. Enter http://서버_IP_주소:81 (e.g., http://192.168.1.100:81)

4.2. Initial login information

Use the following basic account information for your first login

  • Email: admin@example.com
  • Password: changeme

After logging in, you will be prompted to Make sure to change your email address and password for security purposes, please do so immediately 🔒.

4.3. Add Proxy Hosts (Proxy Hosts)

Now let’s add a core feature of NPM: ‘Proxy Hosts’.

  1. in the NPM dashboard, click ‘Hosts’ -> ‘Proxy Hosts’ in the left menu.

  2. Click the ‘Add Proxy Host’ button in the top right corner.

  3. Set the following settings on the Details tab:**

    • Domain Names: Enter the domain names that will be accessed by this proxy host. (Example: blog.your-domain.com) You can add multiple.
    • Scheme: Select the protocol (HTTP or HTTPS) for the internal service. Most use http.
    • Forward Hostname / IP: Enter the IP address or hostname of the server the internal service is running on. (For example, 192.168.1.10 or my-app-server)
    • Forward Port: Enter the port number that the internal service is using. (For example, 2368 for Ghost, 8000 for Django)
    • Block Common Exploits: This option blocks common web attacks. We recommend enabling it.
    • Websockets Support: Enable if your service uses websockets (e.g. Home Assistant, chat apps).

    NPM Proxy Host Details Example (Example: blog.your-domain.com -> http://192.168.1.10:2368)

  4. Set up the SSL tab:**

    • SSL Certificate: Select Request a new SSL Certificate.
    • Force SSL: Force HTTP requests to be redirected to HTTPS. Be sure to enable this for security.
    • HTTP/2 Support: Use the latest HTTP/2 protocol. Recommended to enable for better performance.
    • I Agree to the Let's Encrypt Terms of Service: Check to agree to the terms.
    • Email Address for Let's Encrypt: Enter an email address to receive notifications about Let’s Encrypt.

    NPM Proxy Host SSL Example

  5. Advanced Tab (Optional):

    • If there are any directives you want to add directly to your Nginx configuration file, enter them here. For example, you may want to add specific caching rules or security headers.
    • Example:
      add_header X-Frame-Options "SAMEORIGIN";
      add_header X-Content-Type-Options "nosniff";
  6. Click the ‘Save’ button when you’re done.

After a few moments, NPM will automatically issue an SSL certificate via Let’s Encrypt and apply the Nginx settings. If everything went well, you can now connect to the domain you set up, like https://blog.your-domain.com, and check out your service! ✨

4.4. Other Utilizations

  • Redirection Hosts: Use to redirect a specific domain to a different URL (e.g. old-site.com -> new-site.com)
  • 404 Hosts: Sets the default 404 error page for pages that don’t exist.
  • Streams: Use to set TCP/UDP port forwarding (useful for forwarding traffic from protocols other than HTTP/HTTPS)
  • Users: Manage additional users who can access the NPM administration pages.
  • Audit Log: Allows you to view a history of all configuration changes and events that occurred in NPM. Useful for debugging in case of problems.

⚠️ 5. Tips and Precautions

  • Make sure to set up DNS! In order for NPM to successfully obtain a Let’s Encrypt certificate and access the service externally, the domain you are setting up MUST point to the public IP address of the server where NPM is installed. Your domain registrar or DNS management service will need to set up the A record (your-domain.com -> server_IP_address) or CNAME record (sub.your-domain.com -> your-domain.com or another domain) correctly.
  • Firewall settings. Ports **80 (HTTP), 443 (HTTPS), and 81 (NPM admin page) must be open for external access on your server’s firewall (e.g., ufw or your cloud service’s security group).
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw allow 81/tcp
    sudo ufw reload
  • Back up your data 💾 The npm_data, npm_letsencrypt, and npm_db volumes defined in the docker-compose.yml file store all of NPM’s settings, certificates, and database information. It is important to back up these volumes regularly in case something happens to your server. (Example: docker cp nginx-proxy-manager:/data ./npm_data_backup)
  • Resolve port conflicts. If port 80 or 443 on your server is already in use by another web server (Apache, Nginx, etc.), you can change the host port for NPM by modifying your Docker Compose file.
    ports:
      - '8080:80' # Connect port 8080 on your host to port 80 on NPM.
      - '8443:443' # Connect your host's port 8443 to NPM's port 443
      - '81:81'

    This change will require external connections to be made to http://your-domain.com:8080 or https://your-domain.com:8443, which is not recommended, and it is preferable to have NPM use ports 80/443 exclusively if possible. Consider taking down your existing web server or configuring NPM to sit in front of your existing web server.

  • Higher security.
    • Set the password for the NPM administrator account to something strong and hard to guess.
    • Keep NPM and the underlying Docker image up to date to patch security vulnerabilities (docker compose pull followed by docker compose up -d)
  • **Internal services are HTTP! Because NPM works as a reverse proxy, internal services (e.g., Node.js apps, Apache servers) don’t need to be configured as HTTPS: NPM takes HTTPS requests from the outside, forwards them to the internal service as HTTP, and forwards the internal service’s response back to the outside as HTTPS. This reduces administrative complexity.

✅ Conclusion

Nginx Proxy Manager is a powerful tool for running web services that dramatically simplifies the cumbersome Nginx setup and SSL certificate management. By leveraging Docker Compose, you can build a fully functional NPM environment in just a few minutes, and the intuitive web UI makes it easy to manage all your services.

With Nginx Proxy Manager, you too can save time on web service management and focus on more important tasks. If you have any questions, feel free to ask them in the comments! Happy server running! 💻✨

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다