Bare metal / VM install instructions - not the entire world is docker
Is your feature request related to a problem? Please describe.
The world is not docker. There are use cases for it, but there are a lot of uses cases where docker is not the best solution. Just providing install instructions for docker leaves out those situations where something else than docker is required / needed / decided upon / forced, nginx runs on a lot of platforms, not only on docker. There may be unsupported architectures in use (risc-v, cheri, powerpc, ...), there may be unsupported OS in use (*BSDs), there may be a requirement that it runs in a VM (no matter if because of policy, security reasons, or whatever), and so on... where your project would run simply fine. It also prevents an OS specific package management to pickup your project as an easy package install. There may also be a security requirement that the software bill of materials is easily inspectable and that open source stuff has to be manually fixable independently from the original developer, that no pre-build image from an unknown source is allowed to be installed.
The dockerfile is not an install instruction. You are locking yourself into a niche instead of opening yourself to the entire open source ecosystem.
Describe the solution you'd like
Provide bare metal install instructions (list of requirements, initial config, where to install what from your repo).
Hi netchild,
if you have Proxmox, you can easy install NPM - Nginx Proxy Manager in an LXC Container with the [Proxmox VE Helpder-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts?id=nginxproxymanager).
Default settings: OS: Debian 12 CPU: 2vCPU RAM: 1GB HDD: 4GB
The Proxmox VE Helper script executes this script, among others.
I have adapted this script that the following script will do perform a "bare metal" installation (Version 2.12.3). Since I am currently still on version 2.11.3 and would like to upgrade to 2.12.XXX, but version 2.12.3 (latest) is not working properly for me (streams not working), I also added version 2.12.0 till 2.12.2 as a comment in the script.
Search for Keyword: ######LATETEST RELEASE there you can comment out/in the necessary Version.
#!/usr/bin/env bash
echo "Installing Dependencies"
apt-get update
apt-get -y install \
sudo \
mc \
curl \
gnupg \
make \
gcc \
g++ \
ca-certificates \
apache2-utils \
logrotate \
build-essential \
git
echo "Installed Dependencies"
echo "Installing Python Dependencies"
apt-get install -y \
python3 \
python3-dev \
python3-pip \
python3-venv \
python3-cffi \
python3-certbot \
python3-certbot-dns-cloudflare
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
pip3 install certbot-dns-multi
python3 -m venv /opt/certbot/
echo "Installed Python Dependencies"
VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
echo "Installing Openresty"
wget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg
echo -e "deb http://openresty.org/package/debian bullseye openresty" >/etc/apt/sources.list.d/openresty.list
apt-get update
apt-get -y install openresty
echo "Installed Openresty"
echo "Installing Node.js"
bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh)
source ~/.bashrc
nvm install 16.20.2
ln -sf /root/.nvm/versions/node/v16.20.2/bin/node /usr/bin/node
echo "Installed Node.js"
echo "Installing pnpm"
npm install -g [email protected]
echo "Installed pnpm"
######LATETEST RELEASE
RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
#RELEASE=2.12.2
##wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
#RELEASE=2.12.1
##wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
#RELEASE=2.12.0
##wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
cd ./nginx-proxy-manager-${RELEASE}
echo "Downloaded Nginx Proxy Manager v${RELEASE}"
echo "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/bin/certbot /opt/certbot/bin/certbot
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
#sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json
#sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r docker/rootfs/var/www/html/* /var/www/html/
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null
fi
mkdir -p /app/global /app/frontend/images
cp -r backend/* /app
cp -r global/* /app/global
echo "Set up Enviroment"
echo "Building Frontend"
cd ./frontend
pnpm install
pnpm upgrade
pnpm run build
cp -r dist/* /app/frontend
cp -r app-images/* /app/frontend/images
echo "Built Frontend"
echo "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
cd /app
pnpm install
echo "Initialized Backend"
echo "Creating Service"
cat <<'EOF' >/lib/systemd/system/npm.service
[Unit]
Description=Nginx Proxy Manager
After=network.target
Wants=openresty.service
[Service]
Type=simple
Environment=NODE_ENV=production
ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250
WorkingDirectory=/app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
echo "Created Service"
#??motd_ssh
#??customize
echo "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
systemctl enable -q --now openresty
systemctl enable -q --now npm
echo "Started Services"
echo "Cleaning up"
rm -rf ../nginx-proxy-manager-*
systemctl restart openresty
apt-get -y autoremove
apt-get -y autoclean
echo "Cleaned"
echo "FINISH"
echo ""
echo ""
IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
PORT=81
echo "Open $IP:$PORT"
echo "Username: [email protected]"
echo "Password: changeme"
__--There we have the salad --__ 🤗
Hi @B0F1B0, may I ask if your setup works at all?
I'm using the latest version of NPM through the PVE Helper Scripts. But the proxy hosts are not working with my custom-ssl. I even tried it without SSL, but the hosts are being redirects to https for some unknown reason and I get some ssl invalid end of file error. I'm confused. I checked my configuration several times but I don't know if the problem is with the npm or not.
Hi @B0F1B0, may I ask if your setup works at all?
I'm using the latest version of NPM through the PVE Helper Scripts. But the proxy hosts are not working with my custom-ssl. I even tried it without SSL, but the hosts are being redirects to https for some unknown reason and I get some ssl invalid end of file error. I'm confused. I checked my configuration several times but I don't know if the problem is with the npm or not.
Hi @mokhos
The latest PVE Helper Scripts install Version 2.12.3 and with that, i had no trouble with proxy-host and Let's Encrypt Certificates. I did not use any custom ssl. I had trouble with streams, so at the moment i am testing 2.12.2. There i had no trouble at the moment.
i even testet 2.12.3 without SSL-Certificates and it also worked, but only with firefox, because brave allways wants https.
Hi @B0F1B0
Could you be so kind to provide instructions how to downgrade the Proxmox installation to 2.12.2, as I need to proxying streams and the latest version has a problem with it - 500 Internal System Error:
structuredClone is not defined
Hi @o10g
I tried to downgrade NPM 2.12.3 to 2.12.2 but this does not work properly.I cant Login anymore.
The only solution I see here is to manually install NPM 2.12.2 in an LXC container as described above.
OS: Debian 12 CPU: 2vCPU RAM: 1GB HDD: 4GB
Here is the script from above, which explicitly installs NPM 2.12.2.
#!/bin/bash
echo "Installing Dependencies"
apt-get update
apt-get -y install \
sudo \
mc \
curl \
gnupg \
make \
gcc \
g++ \
ca-certificates \
apache2-utils \
logrotate \
build-essential \
git
echo "Installed Dependencies"
echo "Installing Python Dependencies"
apt-get install -y \
python3 \
python3-dev \
python3-pip \
python3-venv \
python3-cffi \
python3-certbot \
python3-certbot-dns-cloudflare
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
pip3 install certbot-dns-multi
python3 -m venv /opt/certbot/
echo "Installed Python Dependencies"
VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
echo "Installing Openresty"
wget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg
echo -e "deb http://openresty.org/package/debian bullseye openresty" >/etc/apt/sources.list.d/openresty.list
apt-get update
apt-get -y install openresty
echo "Installed Openresty"
echo "Installing Node.js"
bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh)
source ~/.bashrc
nvm install 16.20.2
ln -sf /root/.nvm/versions/node/v16.20.2/bin/node /usr/bin/node
echo "Installed Node.js"
echo "Installing pnpm"
npm install -g [email protected]
echo "Installed pnpm"
######LATETEST RELEASE
#RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
# grep "tag_name" |
# awk '{print substr($2, 3, length($2)-4) }')
#wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
RELEASE=2.12.2
wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
#RELEASE=2.12.1
##wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
#RELEASE=2.12.0
##wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
cd ./nginx-proxy-manager-${RELEASE}
echo "Downloaded Nginx Proxy Manager v${RELEASE}"
echo "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/bin/certbot /opt/certbot/bin/certbot
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
#sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json
#sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r docker/rootfs/var/www/html/* /var/www/html/
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null
fi
mkdir -p /app/global /app/frontend/images
cp -r backend/* /app
cp -r global/* /app/global
echo "Set up Enviroment"
echo "Building Frontend"
cd ./frontend
pnpm install
pnpm upgrade
pnpm run build
cp -r dist/* /app/frontend
cp -r app-images/* /app/frontend/images
echo "Built Frontend"
echo "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
cd /app
pnpm install
echo "Initialized Backend"
echo "Creating Service"
cat <<'EOF' >/lib/systemd/system/npm.service
[Unit]
Description=Nginx Proxy Manager
After=network.target
Wants=openresty.service
[Service]
Type=simple
Environment=NODE_ENV=production
ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250
WorkingDirectory=/app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
echo "Created Service"
#??motd_ssh
#??customize
echo "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
systemctl enable -q --now openresty
systemctl enable -q --now npm
echo "Started Services"
echo "Cleaning up"
rm -rf ../nginx-proxy-manager-*
systemctl restart openresty
apt-get -y autoremove
apt-get -y autoclean
echo "Cleaned"
echo "FINISH"
echo ""
echo ""
IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
PORT=81
echo "Open $IP:$PORT"
echo "Username: [email protected]"
echo "Password: changeme"
@o10g @B0F1B0
Streams is having an issue because you need a higher version of node. 17.9.1 works.
The error is structuredClone is not defined, which was a function added in node v17. So make sure to update npm.service to use like nvm 17 path and not usr/bin/node. Let me know if you need help, this got my streams working on Proxy Manager v2.12.3
I am running 2.12.3 from proxmox helper scripts. on an unpriv LXC on Proxmox.
If this is of any help i did the following to get streams working.
nvm install node
nvm use node
nvm alias default node
confirmed node version
node -v
for me it was v24.0.1
then i updated the npm.service unit ( /lib/systemd/system/npm.service ) to the following
[Unit]
Description=Nginx Proxy Manager
After=network.target
Wants=openresty.service
[Service]
Type=simple
Environment=NODE_ENV=production
ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
ExecStart=/root/.nvm/versions/node/v24.0.1/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250
# ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250
WorkingDirectory=/app
Restart=on-failure
[Install]
WantedBy=multi-user.target
Note the former ExecStart is commented out for reference.
Ensure your node version matches that on the ExecStart line.
systemctl daemon-reload
systemctl restart npm.service
I was then able to create streams.
I have to agree with 'not the entire world is docker' - for example I use a Ubuntu LXD/LXC environment. I could run a docker or podman container inside my LXC container but what is the point of having a box in a box? I'm considering to publish a git-repository for 'Nginx Proxy Manager on Bare Metal' - share your thoughts on this.
Here my Script (NPM Version 2.13.2), it should work on Bare Metal / VMs / and Container.
#!/usr/bin/env bash
#
# Nginx Proxy Manager LXD Installation Script Version 0.8
# Author: AI[den] ;-)
# Date: 2025-11-08
# Description: Installs Nginx Proxy Manager in an LXC container for LXD environments
# License: GPL3 | https://www.gnu.org/licenses/gpl.txt
# Source: https://community-scripts.github.io/ProxmoxVE/scripts?id=nginxproxymanager
# Source: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4420
set -e # Exit on any error
echo "Installing Dependencies"
apt-get update
apt-get -y install \
sudo \
nano \
tree \
mc \
curl \
wget \
gnupg \
ca-certificates \
make \
gcc \
g++ \
apache2-utils \
logrotate \
build-essential \
git \
golang-go
echo "Installing Node.js 22.x"
# Install Node.js 22.x from NodeSource
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get update
apt-get install -y nodejs
echo "Installing yarn"
npm install -g yarn
echo "Installing Python Dependencies"
apt-get install -y \
python3 \
python3-dev \
python3-pip \
python3-venv \
python3-cffi \
python3-certbot \
python3-certbot-dns-cloudflare
# Remove externally-managed restriction for pip
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED 2>/dev/null || true
# Install certbot-dns-multi with build dependencies
apt-get install -y pkg-config libssl-dev
pip3 install --break-system-packages certbot-dns-multi
echo "Installing Openresty"
# Import GPG key and add repository
wget -O - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty.gpg
# Get the codename dynamically
codename=$(grep -Po 'VERSION="[0-9]+ \(\K[^)]+' /etc/os-release)
echo "deb http://openresty.org/package/debian $codename openresty" \
| tee /etc/apt/sources.list.d/openresty.list
# Update and install openresty
apt-get update
apt-get -y install openresty
###### LATEST RELEASE
RELEASE='2.13.2'
RELEASE_FILE="v${RELEASE}.tar.gz"
echo "Downloading Nginx Proxy Manager v${RELEASE}"
cd /root
# Clean up any previous failed attempts
rm -rf nginx-proxy-manager-* 2>/dev/null || true
# Use the correct URL
wget -q https://github.com/NginxProxyManager/nginx-proxy-manager/archive/refs/tags/${RELEASE_FILE} -O nginx-proxy-manager-${RELEASE}.tar.gz
# Check if download was successful
if [ ! -f "nginx-proxy-manager-${RELEASE}.tar.gz" ]; then
echo "ERROR: Download failed!"
exit 1
fi
echo "Extracting NPM..."
tar -xzf nginx-proxy-manager-${RELEASE}.tar.gz
# Check if extraction was successful
if [ ! -d "nginx-proxy-manager-${RELEASE}" ]; then
echo "ERROR: Extraction failed!"
exit 1
fi
cd nginx-proxy-manager-${RELEASE}
echo "Successfully downloaded and extracted Nginx Proxy Manager v${RELEASE}"
echo "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
# FIX: Remove the problematic certbot symlink - it's not needed since certbot is already in PATH
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
# Fix version in package.json files
if [ -f "backend/package.json" ]; then
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
fi
if [ -f "frontend/package.json" ]; then
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
fi
# Update nginx configuration
if [ -f "docker/rootfs/etc/nginx/nginx.conf" ]; then
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
sed -i 's/user npm/user root/g' docker/rootfs/etc/nginx/nginx.conf
fi
# Update nginx include paths
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
# Create directories and copy files
mkdir -p /var/www/html /etc/nginx/logs
if [ -d "docker/rootfs/var/www/html" ]; then
cp -r docker/rootfs/var/www/html/* /var/www/html/ 2>/dev/null || true
fi
if [ -d "docker/rootfs/etc/nginx" ]; then
cp -r docker/rootfs/etc/nginx/* /etc/nginx/ 2>/dev/null || true
fi
[ -f "docker/rootfs/etc/letsencrypt.ini" ] && cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
[ -f "docker/rootfs/etc/logrotate.d/nginx-proxy-manager" ] && cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf 2>/dev/null || true
rm -f /etc/nginx/conf.d/dev.conf 2>/dev/null || true
# Create necessary directories
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
# Create resolvers config
mkdir -p /etc/nginx/conf.d/include
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
# Generate dummy certificate if needed
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
-subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" \
-keyout /data/nginx/dummykey.pem \
-out /data/nginx/dummycert.pem &>/dev/null
fi
# Copy application files
mkdir -p /app/frontend/images
[ -d "backend" ] && cp -r backend/* /app/ 2>/dev/null || true
echo "Set up Environment"
echo "Building Frontend"
if [ -d "frontend" ]; then
cd frontend
# Replace node-sass with sass (key insight from Proxmox script)
if [ -f "package.json" ]; then
sed -E -i 's/"node-sass" *: *"([^"]*)"/"sass": "\1"/g' package.json
fi
# Set Node.js options for build
export NODE_OPTIONS="--max_old_space_size=2048 --openssl-legacy-provider"
# Install dependencies and build with yarn
yarn install --network-timeout 600000
yarn build
mkdir -p /app/frontend
cp -r dist/* /app/frontend/ 2>/dev/null || true
[ -d "public/images" ] && cp -r public/images/* /app/frontend/images/ 2>/dev/null || true
cd ..
else
echo "WARNING: frontend directory not found"
fi
echo "Built Frontend"
echo "Initializing Backend"
mkdir -p /app/config
rm -rf /app/config/default.json 2>/dev/null || true
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
if [ -d "/app" ]; then
cd /app
yarn install --network-timeout 600000
else
echo "WARNING: /app directory not found"
fi
echo "Initialized Backend"
echo "Creating Service"
mkdir -p /lib/systemd/system
cat <<'EOF' >/lib/systemd/system/npm.service
[Unit]
Description=Nginx Proxy Manager
After=network.target
Wants=openresty.service
[Service]
Type=simple
Environment=NODE_ENV=production
ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250
WorkingDirectory=/app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
echo "Starting Services"
# Update nginx configuration
if [ -f "/usr/local/openresty/nginx/conf/nginx.conf" ]; then
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
fi
if [ -f "/etc/logrotate.d/nginx-proxy-manager" ]; then
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
fi
systemctl enable -q openresty
systemctl enable -q npm
systemctl stop openresty 2>/dev/null || true
systemctl stop npm 2>/dev/null || true
systemctl start openresty
systemctl start npm
echo "Cleaning up"
cd /root
rm -rf nginx-proxy-manager-* 2>/dev/null || true
apt-get -y autoremove
apt-get -y autoclean
echo "FINISH"
echo ""
echo ""
IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
PORT=81
echo "Open http://$IP:$PORT"