In today’s Nginx proxy manager tutorial Part 1, we will be installing NGINX Proxy Manager Docker on our Raspberry Pi 4.
This is episode 6 in our Raspberry Pi Series. In this episode, we will cover how to install Nginx Proxy Manager and in our next episode, we will show you how to use it with Nextcloud. So stay tuned for that.
Note: Updated 24/10/2021
Difficulty=Medium
Introduction to NGINX PROXY MANAGER:
NGINX Proxy manager is a must-have for any server administrator who would like to safely open up a port, service or application to the internet.

What NGINX Proxy Manager does is act as a reverse proxy allowing the management of incoming connections to be redirected to the correct device and service. This is all done internally and the outside visitor will be unaware that this process has taken place.
It adds a layer of security for your devices that are hosting the service or application as it does not directly expose that device to the internet.
It also means that you can limit the ports you open on your gateway router. If you were not using a reverse proxy then you will need to open a port for each service application you use. Using NGINX Proxy manager means you only need to open two ports and the proxy manager will take care of the rest.

Another amazing feature of NGINX Proxy Manager is its ability to create Let’s Encrypt SSL/TLS certificates creating an encrypted connection between your outside visitor’s browser and your internal service or application. This allows for safe communication of sensitive data.
Prerequisites:
- A Raspberry Pi with Raspberry Pi OS installed.
- Secured Raspberry Pi.
- Openmediavault, Docker and Portainer Installed.
- You will need to know your Router credentials and how to forward ports.
How to install Nginx Proxy Manager & Mariadb.
First, you need to be connected to your Raspberry Pi 4 through SSH. You can do this by installing PuTTY on Windows or by opening a Terminal session on Linux or Mac.
Once connected we need to create a folder so type the following and press “enter“:
mkdir nginx
Now we need to move into that directory using the following and press “enter“:
cd nginx
We now need to create the file config.json use the following to open the nano editor so we can input some data then press “enter”.
nano config.json
Now we have a file to write to copy and paste the following into the file.
Note: Replace all “changeme” values with something unique and secure.
Note: The below details have been updated and are confirmed working as of 24th October 2021.
{ "database": { "engine": "mysql", "host": "db", "name": "npm", "user": "changeme", "password": "changeme", "port": 3306 } }
Once you have done that press “Ctrl + X” then Y to save and “Enter” to exit the nano editor.
We now have to create one more file this one is a docker-compose.yml file.
Type the following to create the file in the nano editor:
nano docker-compose.yml
Like before change all “changeme” values to match the same as set in the config.json file.
Note: Create a new password for MYSQL_ROOT_PASSWORD.
If you are using an external drive to store your container data, change the folder location under “volumes:” before the colon : to your desired location. Leave all ports values the same.
version: '3' services: app: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '80:80' - '81:81' - '443:443' environment: DB_MYSQL_HOST: "db" DB_MYSQL_PORT: 3306 DB_MYSQL_USER: "changeme" DB_MYSQL_PASSWORD: "changeme" DB_MYSQL_NAME: "npm" volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt db: image: 'jc21/mariadb-aria:latest' restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: 'changeme' MYSQL_DATABASE: 'npm' MYSQL_USER: 'changeme' MYSQL_PASSWORD: 'changeme' volumes: - ./data/mysql:/var/lib/mysql
Once you have done that press “Ctrl + X” then Y to save and “Enter” to exit the nano editor.
To deploy the dockers run the following command:
sudo docker-compose up -d
This will take some time to finish.
Once complete you can check that the docker containers exist by typing the following:
sudo docker ps
Or you can check in Portainer by logging in via your browser and navigating to “Containers“.
Note: Replace RASPBERRYPIIP with your raspberry pi IP address followed by port 9000. Example “http:192.168.2.5:9000”
http:RASPBERRYPIIP:9000

If you see any problems like “unhealthy” Please restart the container and all should be well.
How to connect to the NGINX PROXY Manager Dashboard
Open a browser window and type the following into your address bar.
Note: Replace RASPBERRYPIIP with your raspberry pi IP address followed by port 81. Example “http:192.168.2.5:81”
http:RASPBERRYPIIP:81

The default login credentials are:
Username: [email protected] Password: changeme
You will be prompted to Edit the User fields. Enter your credentials and click “Save“

You will then be asked to change your the default current password from “changeme” to your own secure password.

Forward port 80 and 443 from your Router to your Raspberry Pi.
You will now need to port forward both ports 80 and 443 from within your Router to your Raspberry Pi’s IP address and internal ports 80 and 443.
There are so many different router models on the market so we recommend searching on Google “how to port forward on ROUTER MODEL NAME” to get a detailed guide for your router.

NGINX Mariadb fix.
If all is working fine you can ignore this Mariadb fix below.
If you have any problems with the mariadb and in the logs you get [Global ] › ✖ error. Here is the fix.
1: Stop both containers NGINX App and Mariadb from within Portainer.
2: SSH into your Raspberry Pi
ssh -p PORT [email protected]
Navigate to your NGINX data folder:
cd /home/user1/nginx/data/mysql
3: List out the files in the directory
ls
4: Remove the log files “ib_logfile0” and “aria_log.00000001” and “aria_log_control”
sudo rm ib_logfile0
sudo rm aria_log.00000001
sudo rm aria_log_control
5: Go back to Portainer and restart the mariadb container first check the logs the database should be working now and you should see
“Version: ‘10.5.9-MariaDB’ socket: ‘/run/mysqld/mysqld.sock’ port: 3306 MariaDB Server”
6: Now restart the NGINX App and it should boot to “healthy” if it doesn’t restart it a final time :).
We need your support.
We hope you enjoyed this episode and that it was helpful and you got benefit out of it.
If you did, please consider supporting our channel by Subscribing to our YouTube channel, and liking and sharing our content.
You can also make a donation via Paypal or become a Patreon if you wish to do so.
You can also follow us on Facebook or Twitter.
If you have any questions or any requests please ask in the comments below or on YouTube.
Hi!
Noob here. My nginx_app_1 container is showing as “unhealthy” even after a restart. I checked the logs and its showing:
ER_ACCESS_DENIED_ERROR: Access denied for user ‘npm’@’ipaddress’ (using password: YES)
Not sure what to do here.. any suggestions?
it could be that your password was not entered correctly. Try recreating the stack and supply a different password. Try to avoid any quotations or special characters.
Let us know how you get on..
Hello,
I get the same issue with “unhealthy”. I didn’t change anything and kept “npm” everywhere.
I just follow this tupo and copy/path everything.
Unfortunately same issue :
nginx_db_1 log :
Version: ‘10.4.15-MariaDB’ socket: ‘/run/mysqld/mysqld.sock’ port: 3306 MariaDB Server,
2021-03-14 19:21:40 8 [Warning] Access denied for user ‘npm’@’172.18.0.3’ (using password: YES),
nginx_app_1 log :
[3/14/2021] [7:21:33 PM] [Global ] › ℹ info Generating MySQL db configuration from environment variables,
[3/14/2021] [7:21:33 PM] [Global ] › ℹ info Wrote db configuration to config file: ./config/production.json,
[3/14/2021] [7:21:40 PM] [Global ] › ✖ error ER_ACCESS_DENIED_ERROR: Access denied for user ‘npm’@’172.18.0.3’ (using password: YES),
I also try several yml file, change PSW, make lot of try, but each time same final result of Access denied for user.
Permissions are set to sudo chmod -R 777 into home folder.
Really I’m stuck here since 3 days 🙁
Any idea to help me?
Thanks in advance.
Have you tried restarting the containers?.
Damned!!!
I got it after a last try.
I replace volumes locations and set to my external SDD.
version: ‘3’
services:
app:
image: ‘jc21/nginx-proxy-manager:latest’
ports:
– ’80:80′
– ’81:81′
– ‘443:443’
environment:
DB_MYSQL_HOST: “db”
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: “npm”
DB_MYSQL_PASSWORD: “npm”
DB_MYSQL_NAME: “npm”
volumes:
– /srv/dev-disk-by-uuid-7eda5ea05db9/Config/nginx/srv/data:/data
– /srv/dev-disk-by-uuid-7eda5ea05db9/Config/nginx/letsencrypt:/etc/letsencrypt
db:
image: ‘yobasystems/alpine-mariadb:latest’
environment:
MYSQL_ROOT_PASSWORD: ‘npm’
MYSQL_DATABASE: ‘npm’
MYSQL_USER: ‘npm’
MYSQL_PASSWORD: ‘npm’
volumes:
– /srv/dev-disk-by-uuid-7eda5ea05db9/Config/nginx/data/mysql:/var/lib/mysql
Yayyy!
Now, just need to redo same with something more secure and change all “npm”.
Br.
I installed it I can open the web but when I put in user name [email protected], and password changeme, it display a bad getway error, it looks everything is correct, but I cant login 🙁
Try restarting the containers. If not recreate it. Let us know how you get on.
I got the same error when I try to login. I restarted the containers and still.
Below is my yml
GNU nano 3.2 docker-compose.yml
version: ‘3’
services:
app:
image: ‘jc21/nginx-proxy-manager:latest’
ports:
– ’80:80′
– ’81:81′
– ‘443:443’
environment:
DB_MYSQL_HOST: “db”
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: “khaled”
DB_MYSQL_PASSWORD: “hagarsoriasep85”
DB_MYSQL_NAME: “thenammu”
volumes:
– /srv/dev-disk-by-uuid-6ba6c389-8aff-42f1-847f-9ec7a861fd38/data:/data
– /srv/dev-disk-by-uuid-6ba6c389-8aff-42f1-847f-9ec7a861fd38/letsencrypt:/etc/letse$
db:
image: ‘yobasystems/alpine-mariadb:latest’
environment:
MYSQL_ROOT_PASSWORD: ‘Hagarsoriasep859’
MYSQL_DATABASE: ‘thanammu’
MYSQL_USER: ‘khaled’
MYSQL_PASSWORD: ‘hagarsoriasep85’
volumes:
– /srv/dev-disk-by-uuid-6ba6c389-8aff-42f1-847f-9ec7a861fd38/data/mysql:/var/lib/my$
Any hep would be appreciated please
I have spend days trying to get this to work and nothing works. I have watched every video I can find, tried every variation I could find, Nothing works. Access denied for user, can’t login, bad gateway, unhealthy container….. At this point, I don’t know what else to do but throw in the towel .
I went through every video in this series. In my opinion, it is the best series of videos I have seen on youtube pertaining to these complex topics. I was able to replicate almost everything as I followed along. This nginx proxy manager thing has been perhaps the most difficult part of all of this. I have had to spend hours trying to get a healthy container up and running. After a lot of trial and error, I figured what worked, atleast for me that is. Maybe others got it to work a different way but this is what I had to do:
I copied & pasted the content of both the .yml file and the config.json file from
your site. I had to swap the image you have in the .yml file for the one that is on
the nginx proxy manager official site:
yobasystems/alpine-mariadb:latest for ‘jc21/mariadb-aria:latest’
The other thing that I had to do was leave all of the parts that said ‘npm’ as
such. It seems that whenever I tried to change them, I got some type of
permission error. The only way I got this to work, after many, many attemptswas
to leave it as is to get the container up and running and then change then after the fact. In your video, you do the same thing, that is, you leave them at their
default and encourage everyone to change them. You had to have had the
same issue, right?
Hi there thanks for the tutorial. I get ‘Gateway Error’ irrespective of how many times I restart the docker
[4/26/2021] [4:21:38 PM] [Global ] › ✖ error connect ECONNREFUSED 172.18.0.2:3306,
I have no firewall running etc.
Did you find a fix for this
Use this ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’
instead of ‘yobasystems/alpine-mariadb:latest’
This worked!!!
Sasa, Thanks for your comment, and it helped me to solve a bad gateway error at the Nginx proxy manager
For those who didn’t get it, you need to make the changes that SaSa suggested in home/pi/nginx/docker-compose.yml
Thank you so much Sasa! I was having the same issue and this resolved it!
Same error here
[4/29/2021] [8:33:44 PM] [Global ] › ✖ error connect ECONNREFUSED 172.19.0.2:3306
I also get the ECONNREFUSED 172.19.0.2:3306 error. Any guesses?
I had the same issue. Try to install with this image:
image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’
instead of this one:
image: ‘yobasystems/alpine-mariadb:latest’
Thanks, this worked to solve [Global ] › ✖ error connect ECONNREFUSED.
to who that might be struggle with files below are the content of two files :
nano config.json
{
“database”: {
“engine”: “mysql”,
“host”: “db”,
“name”: “npm”,
“user”: “changeme”,
“password”: “changeme”,
“port”: 3306
}
}
nano docker-compose.yml
version: “3”
services:
app:
image: ‘jc21/nginx-proxy-manager:latest’
restart: always
ports:
– ’80:80′
– ‘443:443′
– ’81:81’
environment:
DB_MYSQL_HOST: “db”
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: “changeme”
DB_MYSQL_PASSWORD: “changeme”
DB_MYSQL_NAME: “npm”
DISABLE_IPV6: ‘true’
volumes:
# this location for my SD feel free to change yours
– ./data/nginx-proxy-manager:/data
– ./letsencrypt:/etc/letsencrypt
depends_on:
– db
db:
# finally working image of maria db
image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’
restart: unless-stopped
environment:
# change below values to be yours
PUID: 1001
PGID: 100
TZ: “Europe/London”
MYSQL_ROOT_PASSWORD: “changeme”
MYSQL_DATABASE: “npm”
MYSQL_USER: “changeme”
MYSQL_PASSWORD: “changeme”
volumes:
# this location for my SD feel free to change yours
– ./data/mariadb:/config
i tried those and worked for me .
HUGE thank-you to Mina and Hill for posting the change to the docker-compose.yml file. I also had the problem where it was showing unhealthy and wouldn’t connect to the database correctly with an error stating that the connection was refused. By changing image: ‘yobasystems/alpine-mariadb:latest’ to image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’ this fixed this issue. I’m unaware at the moment why using latest doesn’t work other than the latest version is corrupted in some way. Maybe someone can shed some light on this?
This finally worked for me. I know little, but it seems like we were trying to install a 64bit MariaDb on a 32bit version of PiOS –
image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’
* You may need to correct the ‘ on front and end if it fails
HUGE thank-you to Mina and Hill for posting the change to the docker-compose.yml file. I also had the problem where it was showing unhealthy and wouldn’t connect to the database correctly with an error stating that the connection was refused. By changing image: ‘yobasystems/alpine-mariadb:latest’ to image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’ this fixed this issue. I’m unaware at the moment why using latest doesn’t work other than the latest version is corrupted in some way. Maybe someone can shed some light on this?
I have an additional issue that I ran into and I’ve just spent the last few hours trying to track down what I’m doing wrong but haven’t been able to find a solution as of yet. My network is currently setup as follows:
Internet Modem/Router –> Netgear Router –> Devices attached
Modem Ext IP Addres s [??? not divulging this information] / Internal IP address 192.168.0.1 –> Router External IP address 192.168.0.3 –> Router Internal IP address 192.168.1.1
I’ve setup port forwarding in the modem to forward incoming traffic on port 80 and on port 443 to go to my routers external IP address of 192.168.0.3.
I’ve setup port forwarding in the router to go to my raspberry pi static IP address of 192.168.1.30
When I goto a browser window and type in my raspberry pi address of http://192.168.1.30:80 it take me to the screen that says “Congratulations! You’ve successfully started the Nginx Proxy Manager.”
When I goto a browser window and type in my modems external internet address and :80 It says the site can’t be reached and displays the IP address and says took too long to respond. ERR_CONNECTION_TIMED_OUT
Can anyone tell me what I am doing wrong here? Due to my network configuration I’m under the impression that I need to forward ports 80 and 443 from my modem to my router and then forward again from my router to my raspberry pi.
Thanks for any help you are able to provide!
Update: I did the following to try and fix this:
1) I put my raspberry pi directly on the zyxel C3000Z modem/router instead of on the other router attached to the Zyxel C3000Z modem/router
2) I made the necessary IP address changes for the pi
3) I tested and was still unable to get the congratulatory message from the proxy server
4) I completely started from scratch, reinstalling and reconfiguring the pi starting from the first lesson but still was met with defeat.
5) I looked up and ensured that I completed the steps for port forwarding on the ZyXEL C3000Z modem/router and verified that I have set this up properly
Is there another way to check to see if these ports are being properly forwarded other than using the browser and checking to see if I get the message from the pi?
This has me stumped!
Update 2: I located a free port scanning software for windows and setup the modem/router to forward port 80 to my PC to verify if it was working or not and this works! So now I suspect that its something to do with the Nginx proxy manager. I can get it to display the message if I use my local IP but it will not display if I use my internet provided IP. Any ideas where else I might look?
FIXED!
Not sure exactly why you are not able to do this but it just appears that you can’t ping or request access to your public IP address from within your LAN. I went to my phone and turned off WiFi to make sure I was not on my LAN. I then typed my public IP address in Chrome on my phone and it worked! All this time troubleshooting and there wasn’t a really a problem.
I ran into an issue where I had restart everything. Now I keep getting a redirecting error stating that the server is redirecting too many times. I’m assuming this has to be Nginx causing this issue. I tried troubleshooting on Google but haven’t found anything. Any ideas where I can look?
hi
Everything is fine until, 16:50 mark, the browser defaults to the router log in if i use my public ip address,
if on the other hand if i use the local ip, or public ip address with a VPN on, or using my moble phone on 4g with the public ip address port 80, it works fine. and get the same as you.
Congratulations!
You’ve successfully started the Nginx Proxy Manager.
If you’re seeing this site then you’re trying to access a host that isn’t set up yet.
Log in to the Admin panel to get started.
im guessing my router does not like to bounce my public ip to my local network
any solutions
Hi,
I really appreciated the serie and I’m following it with a lot of interest.
I’m not an expert but when I have a problem i always try to solve by myself taking help from the net, but this time i really couldn’t solve it.
I installed OMV and Portainer and DuckDns without any problems, but i had some for Nginx.
The main problem is that my IPS is blocking port 80 from remote connection, so I couldn’t install Nginx like you did with the standard parameter “80:80” in port configuration, but i did with “8080:8080” and i could installate it.
I can also access to the administrator page on port 81 without any problem, but can’t reach Nginx when i try to search the domain i did with DuckDns receiving the error “ERR_CONNECTION_TIMED_OUT”.
I hope that someone can help me to solve this problem, giving me the way to change the listen port from 80 to 8080, at least i imagine i should do this.
Thanks in advance to everybody.
have you tried using 8080:80?. Instead of 8080:8080? 🙂
Hi, sorry for the late answer but i could not try before.
Anyway I thank you very a lot for your advice, and it was great.
I re-installed NGINX with port configuration 8080:80 and now I can see the ‘congratulation page’ on my IP:8080.
I installed also DuckDNS and Nextcloud and i wanted to have a domain pointing directly to the raspberry pi IP on port of Nextcloud, that is 8181 like you did in your configuration.
But probably with the different configuration of NGINX that i set, I can’t do like you did in videos because:
On NGINX I set the proxy
with the domain given by DuckDNS pointing to my raspberry pi : 8181 (where should be Nextcloud), but if i try to search my domain I receive HTTP ERROR 404.
Instead, if i search my domain : 8181 i can find my instance of Nextcloud, if I search domain : 81 i can find instances of NGINX..
So, my question is:
with my configuration of NGINX manager it’s normal to work like this?
Or like you i can also have a single domain for a single port? For example 1 domain for Nextcloud on port 8181 and one for NGINX on port 81?
Thanks in advance for you answer.
Big fan of the serie!
Hi,
So i’ve read the lot of poste here and elsewhere about the problem of MariaDB source for the raspberry Pi 4.
So what is the good image to load :
-> jc21/mariadb-aria:latest
(mentionned in the section “Run the app”)
-> yobasystems/alpine-mariadb:latest
(mentionned in the section “Running on Raspberry PI / ARM devices”)
or the one that seems to work for a lot of user :
-> yobasystems/alpine-mariadb:10.4.17-arm32v7
(but the Raspberry Pi 4 is a ARM v8 64-bit SoC, so why this “…arm32v7” version ?)
And last question : is the PUID and PGID needed in the database environnement variable ?
Thanks for your help.
Pierre (french follower of your site 😉
To fix, edit this line in the stack. image: ‘yobasystems/alpine-mariadb:latest’ to be image: ‘yobasystems/alpine-mariadb:10.4.17-arm32v7’ This should fix any problems. Let us know if it helped so we can help others. 🙂
Hi,
really enjoying the videos but I, like a few others have hit a snag with nginx_app_1 appearing unhealthy.
I’ve tried switching from Mariadb latest to an earlier version and deleting the log files but I still seem to be stuck with an unhealthy container.
The log shows a Global X error with ‘connect ECONNREFUSED 172.21.0.2:3306
Any help would be gratefully appreciated
Thanks
Yorky
The previous error may have been something to do with my impatience after restarting .
The log now reads
getaddrinfo ENOTFOUND db
I had to restart this process from scratch at least 5 times and what finally worked was copying and pasting directly from the tutorial without changing the npm values and following the directions to the letter. Then, once the containers are deployed, go back and edit your .json and .yml files to make them secure.
Thanks for the tutorial…wonderfully well described!
I have updated the Docker composed file and it should now work fine without the need for any fixes. Please let me know if you have any further problems.
I’ve tried installing Nginx on a new raspberry pi with the tutorial, but i’m getting these error messages:
Creating nginx_db_1 …
Creating nginx_app_1 …
Creating nginx_app_1 … error
ERROR: for nginx_app_1 Cannot start service app: driver failed programming external connectivity on endpoint nginx_app_1 (1328e216aef32a3fbab7cd76aca08702fccf2Creating nginx_db_1 … done
:443: bind: address already in use
ERROR: for app Cannot start service app: driver failed programming external connectivity on endpoint nginx_app_1 (1328e216aef32a3fbab7cd76aca08702fccf2ba1595f101f5a695c3819a6f5e6): Error starting userland proxy: listen tcp4 0.0.0.0:443: bind: address already in use
ERROR: Encountered errors while bringing up the project.
Hope you can help solve them.
Hello I have tried this several times and the only way I can get it to work is by not changing the “changeme” values. How do I make it work securely with my own values? Thanks!
Hi,
I need help. Getting this error.
ERROR: for nginx_app_1 Cannot start service app: driver failed programming external connectivity on endpoint nginx_app_1 (96d2023962e6a75142ba50d3de3b42d899f25 Creating nginx_db_1 … doneated
ERROR: for app Cannot start service app: driver failed programming external connectivity on endpoint nginx_app_1 (96d2023962e6a75142ba50d3de3b42d899f2593bdb86b a798fa11fa229f90144): Bind for 0.0.0.0:443 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
Also getting this error. I checked netstat and found the processes already using these ports (monocle on 443 and lighttpd (pihole web ui) on 80.
question is, does nginx absolutely need these ports or can i pick different ports? Or must I reconfigure my other services to use other ports?
Hi so when i port forward to port 80 and 443 my public ip doesnt open the proxy manager but my local ip does would anyone know how to fix ?
i mean when i do docker ps i give me the port 0.0.0.0:443 and it wont go to public ip idk what to do
Hello folks, in which of the RasPi series did you covered the instalation of Portainer? Thx for answer!
https://www.addictedtotech.net/how-to-install-openmediavault-5-on-raspberry-pi-4-episode-5/
Quick tip on this one, if you have a separate modem and router you’ll need to forward ports 80 and 443 from the modem to the router and then again from the router to the pi.
Love these guides btw
Can I use this to point to a different ip address with a vpn connection other then the nginx server?
I had trouble with the bad gateway issue, looking at the logs there was an underling issue connecting to the database. I’m not sure why.
I removed the created containers and stack and added a stack via portainer instead of via ssh into the pi. Using exactly the same code as in the yml file and everything set up fine.