nginx reverse proxy solution

Discussion in 'Plugins/Modules/Addons' started by Lindworm, Mar 8, 2026.

  1. Lindworm

    Lindworm New Member

    Hi, I am new here. A veteran webserver admin but until now I choose the easy route Plesk for my servers. Digital independence thoughts and ever rising prices brought me back to taking things for my servers in my own hands. After moving away from Plesk, I chose ISPconfig to manage my servers. It's powerful and flexible, but many of the sites I run are tightly coupled to Apache. So I needed a solution to run nginx as a proxy in front of ISPConfigs apache without inhibiting its functionality in any way, as my customers have the freedom to add and remove domains and all functions should be unattended by me as much as possible.

    So I wrote myself a solution that helps me installing it on my servers. I refined it into a reusable install script and uploaded it on github. I had about 2min of downtime at most on my servers, switching nginx in as a reverse proxy.

    As I am new here, I may not link. You can find it on Github with this search word ispconfig-nginx-reverse-proxy-solution.
    If a person with link rights would link it below, that would be awesome.

    H
    ave fun with it.
     
    nunor, ahrasis and till like this.
  2. till

    till Super Moderator Staff Member ISPConfig Developer

  3. till

    till Super Moderator Staff Member ISPConfig Developer

  4. Alex Mamatuik

    Alex Mamatuik Member

    Hi! I've tried to test it.
    git clone https://github.com/MircoBlitz/ispconfig-nginx-reverse-proxy-solution
    Cloning into 'ispconfig-nginx-reverse-proxy-solution'...
    remote: Enumerating objects: 19, done.
    remote: Counting objects: 100% (19/19), done.
    remote: Compressing objects: 100% (18/18), done.
    remote: Total 19 (delta 4), reused 9 (delta 0), pack-reused 0 (from 0)
    Unpacking objects: 100% (19/19), 25.42 KiB | 531.00 KiB/s, done.
    /tmp
    [root@server tmp] $ cd ispconfig-nginx-reverse-proxy-solution
    /tmp/ispconfig-nginx-reverse-proxy-solution
    [root@server ispconfig-nginx-reverse-proxy-solution] $ sudo bash setup.sh

    ==> Checking prerequisites
    [OK] Running as root
    [OK] ubuntu 20.04 detected
    [OK] ISPconfig installation found
    [OK] Apache2 is running

    ==> Configuration
    ────────────────────────────────────────────────

    This setup places nginx in front of Apache on your ISPconfig server.
    After setup:
    - nginx listens on ports 80 and 443
    - Apache moves to 127.0.0.1:9080 and 127.0.0.1:9443
    - ISPconfig continues to manage Apache vhosts unchanged

    ────────────────────────────────────────────────
    [INFO] Detected ISPconfig panel domain: server.xn----gtbbrigdncckfmo1g9e.xn--p1ai
    Use 'server.xn----gtbbrigdncckfmo1g9e.xn--p1ai'? Press Enter to confirm or type a different domain:

    Install scripts to directory [/root/bin]:
    Directory '/root/bin' does not exist. Create it? (yes/no): yes
    [OK] Created: /root/bin
    [INFO] Scripts will be installed to: /root/bin

    [INFO] Using ISPconfig domain: server.xn----gtbbrigdncckfmo1g9e.xn--p1ai


    ==> Installing nginx and brotli modules
    E: The repository 'https://deb.goaccess.io focal Release' does not have a Release file.
    /tmp/ispconfig-nginx-reverse-proxy-solution

    bash setup.sh --dry-run
    [WARN] DRY-RUN mode: no changes will be made.


    ==> Checking prerequisites
    [OK] Running as root
    [OK] ubuntu 20.04 detected
    [OK] ISPconfig installation found
    [OK] Apache2 is running

    ==> Configuration
    ────────────────────────────────────────────────

    This setup places nginx in front of Apache on your ISPconfig server.
    After setup:
    - nginx listens on ports 80 and 443
    - Apache moves to 127.0.0.1:9080 and 127.0.0.1:9443
    - ISPconfig continues to manage Apache vhosts unchanged

    ────────────────────────────────────────────────
    [INFO] Detected ISPconfig panel domain: server.xn----gtbbrigdncckfmo1g9e.xn--p1ai
    Use 'server.xn----gtbbrigdncckfmo1g9e.xn--p1ai'? Press Enter to confirm or type a different domain:

    Install scripts to directory [/root/bin]:
    [INFO] Scripts will be installed to: /root/bin

    [INFO] Using ISPconfig domain: server.xn----gtbbrigdncckfmo1g9e.xn--p1ai


    ==> Installing nginx and brotli modules
    [DRY-RUN] apt-get update -qq
    [DRY-RUN] apt-get install -y nginx libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
    [OK] nginx will be installed

    ==> Backing up existing configurations
    [INFO] Backup directory: /root/nginx-setup-backup-20260403-033542
    [DRY-RUN] mkdir -p /root/nginx-setup-backup-20260403-033542
    [DRY-RUN] cp /etc/apache2/ports.conf /root/nginx-setup-backup-20260403-033542/
    [OK] Backed up: /etc/apache2/ports.conf

    ==> Deploying nginx.conf
    [DRY-RUN] cp /tmp/ispconfig-nginx-reverse-proxy-solution/configs/nginx.conf /etc/nginx/nginx.conf
    [OK] nginx.conf deployed

    ==> Deploying Apache nginx-proxy conf
    [DRY-RUN] cp /tmp/ispconfig-nginx-reverse-proxy-solution/configs/apache-nginx-proxy.conf /etc/apache2/conf-available/nginx-proxy.conf
    [OK] apache-nginx-proxy.conf deployed
    [DRY-RUN] a2enconf nginx-proxy
    [OK] nginx-proxy conf enabled
    AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/sites-enabled/000-ispconfig.vhost:7
    Syntax OK
    [DRY-RUN] systemctl reload apache2
    [OK] Apache reloaded

    ==> Installing scripts to /root/bin
    [DRY-RUN] mkdir -p /root/bin
    [DRY-RUN] cp /tmp/ispconfig-nginx-reverse-proxy-solution/scripts/nginx-vhost-gen.sh /root/bin/nginx-vhost-gen.sh
    [DRY-RUN] cp /tmp/ispconfig-nginx-reverse-proxy-solution/scripts/nginx-sync.sh /root/bin/nginx-sync.sh
    [DRY-RUN] chmod +x /root/bin/nginx-vhost-gen.sh /root/bin/nginx-sync.sh
    [OK] Scripts installed and made executable

    ==> Stopping nginx
    [OK] nginx was not running (expected)

    ==> MANUAL STEPS REQUIRED
    ────────────────────────────────────────────────

    The following steps must be completed in ISPconfig before nginx can start.
    nginx is currently stopped. Do NOT start it until all steps are done.

    Step A — ISPconfig Admin UI
    1. Log in to ISPconfig as admin
    2. Go to: System → Server Config → Web
    3. Set the following:

    Enable PROXY Protocol: on (all sites)
    Use PROXY Protocol: on (IPv4 + IPv6)
    PROXY Protocol HTTP Port: 9080
    PROXY Protocol HTTPS Port: 9443

    4. Click Save
    5. Go to: Tools → Sync Tools → Resync Websites
    6. Wait for ISPconfig to rewrite all vhost files (check:
    grep -l ':9080' /etc/apache2/sites-enabled/*.vhost | wc -l)

    --- Press any key when done ---

    Step B — Disable HTTP→HTTPS redirects
    nginx will handle HTTP→HTTPS redirects. ISPconfig's built-in redirect
    would cause a redirect loop. Disable it using ONE of these options:

    Option 1 — Via ISPconfig UI (per site):
    For each site: Sites → Website → Redirect → uncheck 'Redirect to HTTPS' and save

    Option 2 — Via MySQL (all sites at once, recommended):
    mysql dbispconfig -e "UPDATE web_domain SET rewrite_to_https = 'n' WHERE rewrite_to_https = 'y';"
    Then resync in ISPconfig: Tools → Sync Tools → Resync Websites

    --- Press any key when done ---

    Step C — Nextcloud (if applicable)
    For each Nextcloud instance, add to config/config.php:

    'trusted_proxies' => ['127.0.0.1'],
    'overwriteprotocol' => 'https',

    --- Press any key when done ---

    Step D — Update ports.conf
    ISPconfig does NOT update /etc/apache2/ports.conf automatically.

    Should this script update ports.conf for you? (yes/no): no

    Do it manually:
    cp /etc/apache2/ports.conf /etc/apache2/ports.conf.bak
    cat > /etc/apache2/ports.conf << 'EOF'
    Listen 9080
    <IfModule ssl_module>
    Listen 9443
    </IfModule>
    EOF
    Then: systemctl restart apache2

    --- Press any key when done ---

    Step E — Verify Apache moved off port 80 and 443
    You should see apache only on port 9080 and 9433

    Current listening ports:
    *:9080 apache2
    *:9443 apache2
    *:8080 apache2
    *:8081 apache2

    Do you still see Apache on port 80 or 443? (yes/no): no
    [OK] Ports look good — Apache is off 80/443
    ────────────────────────────────────────────────

    ==> Generating nginx vhost configs
    [DRY-RUN] /root/bin/nginx-vhost-gen.sh
    [OK] nginx vhost configs generated

    ==> Starting nginx
    [DRY-RUN] nginx -t
    [DRY-RUN] systemctl enable nginx
    [DRY-RUN] systemctl start nginx

    ==> Setting up certbot post-renewal hook
    [DRY-RUN] mkdir -p /etc/letsencrypt/renewal-hooks/post
    [OK] certbot post-renewal hook installed: /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

    ==> Setting up nginx-sync cronjob
    How often should nginx-sync run?
    This determines how quickly nginx picks up changes made in ISPconfig
    (new sites, deleted sites, changed domains). Lower = faster sync.

    1) Every minute — changes apply within 60s (recommended)
    2) Every 2 minutes
    3) Every 5 minutes
    4) Every 10 minutes
    Choose [1-4, default=1]:
    [INFO] Cronjob schedule: * * * * *
    [OK] Cronjob installed: /etc/cron.d/nginx-sync
    [INFO] Log file: /var/log/nginx-sync.log

    ────────────────────────────────────────────────

    Setup complete!

    What's running now:
    - nginx: listening on ports 80 and 443 (TLS termination)
    - Apache: listening on 127.0.0.1:9080 / 9443 (backend)
    - Auto-sync: every minute via cron (nginx-sync.sh)

    Useful commands:
    nginx -t # test nginx config
    systemctl status nginx # nginx status
    journalctl -u nginx -f # nginx logs
    tail -f /var/log/nginx-sync.log # sync log
    /root/bin/nginx-vhost-gen.sh # manual config regeneration

    If something breaks:
    systemctl stop nginx
    cp /etc/apache2/ports.conf.bak /etc/apache2/ports.conf && systemctl restart apache2
    # revert ISPconfig settings (undo PROXY Protocol changes)

    ────────────────────────────────────────────────
    It stated that everything is fine, but nor setup of nginx happened also.

    My aim was to compare your method with mine, because what attracted:
    I believe the tasty one thing - hide all ports behind of 443 nginx, including ISPConfig: it solves DPI and 3rd-party VPN issues.

    But if Mr. Till approves, i wouldn't mind.
     

Share This Page