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 port192.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. TheDB_MYSQL_HOST
uses the name of thedb
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, andnpm_letsencrypt
stores the Let’s Encrypt certificate file.depends_on: - db
: Specifies that theapp
container runs after thedb
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 tomysql: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
andMYSQL_PASSWORD
must be the same asDB_MYSQL_USER
andDB_MYSQL_PASSWORD
in theapp
container).volumes: - npm_db:/var/lib/mysql
: The volume for permanently storing database data.
volumes
: Defines the Named Volumes that will be used in theservices
section. Docker will create and manage them automatically.
For more information, see: #### 3.3. Run NPM
- Create the above
docker-compose.yml
file in the desired directory on your server (e.g.~/npm
). - Navigate to that directory.
cd ~/npm
- 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’.
-
in the NPM dashboard, click ‘Hosts’ -> ‘Proxy Hosts’ in the left menu.
-
Click the ‘Add Proxy Host’ button in the top right corner.
-
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
ormy-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).
(Example: blog.your-domain.com -> http://192.168.1.10:2368)
- Domain Names: Enter the domain names that will be accessed by this proxy host. (Example:
-
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.
- SSL Certificate: Select
-
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";
-
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
, andnpm_db
volumes defined in thedocker-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
orhttps://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 bydocker 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! 💻✨