Skip to content

Instantly share code, notes, and snippets.

@brccabral
Last active August 24, 2026 05:12
Show Gist options
  • Select an option

  • Save brccabral/5d8724df5784ec6a9f02387bb80a6b0b to your computer and use it in GitHub Desktop.

Select an option

Save brccabral/5d8724df5784ec6a9f02387bb80a6b0b to your computer and use it in GitHub Desktop.
Nginx with GoAccess

Nginx Proxy Manager with GoAccess directly

NPM already has a nginx running. Configure the landing page for GoAccess/index.html and create the proxy in NPM that points to the landing page, with the custom /ws paths.

We need two GoAccess', one to parse default-host_access.log and the other for all proxy-host-X_access.log because the log-format are different.
Default-Host uses combined but Proxies use proxy.

  • data/nginx/default_host/site.conf
access_log /data/logs/default-host_access.log combined;
  • data/nginx/proxy_host/1.conf
access_log /data/logs/proxy-host-1_access.log proxy;
networks:
  shared-net:
    external: true

services:
  npm:
    container_name: nginxproxymanager
    image: 'jc21/nginx-proxy-manager:2.15.1'
    restart: unless-stopped
    ports:
      - "443:443"
      - "80:80"
      - "81:81"
    environment:
      TZ: "America/Los_Angeles"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./html:/var/www/html:ro
    networks:
      - shared-net

  goaccess-default:
    image: allinurl/goaccess:1.11
    container_name: goaccess-default
    restart: unless-stopped
    expose:
      - 7890
    volumes:
      - ./data/logs:/logs:ro
      - ./goaccess/default.conf:/etc/goaccess/goaccess.conf:ro
      - ./html/goaccess/default:/var/www/goaccess
    entrypoint:
      - sh
    command:
      - -c
      - 'goaccess
        /logs/default-host*access.log
        --config-file=/etc/goaccess/goaccess.conf
        --real-time-html
        --port=7890
        --ws-url=wss://goaccess.myserver.mydomain:443/default/ws
        --output=/var/www/goaccess/index.html'
    networks:
      - shared-net

  goaccess-proxy:
    image: allinurl/goaccess:1.11
    container_name: goaccess-proxy
    restart: unless-stopped
    expose:
      - 7890
    volumes:
      - ./data/logs:/logs:ro
      - ./goaccess/proxy.conf:/etc/goaccess/goaccess.conf:ro
      - ./html/goaccess/proxy:/var/www/goaccess
    entrypoint:
      - sh
    command:
      - -c
      - 'goaccess
        /logs/proxy-host-*access.log
        --config-file=/etc/goaccess/goaccess.conf
        --real-time-html
        --port=7890
        --ws-url=wss://goaccess.myserver.mydomain:443/proxy/ws
        --output=/var/www/goaccess/index.html'
    networks:
      - shared-net

Create the config files

  • ./goaccess/default.conf
time-format %T
date-format %d/%b/%Y
log-format %h %^ %^ [%d:%t %^] "%r" %s %b "%R" "%u"
  • ./goaccess/proxy.conf
time-format %T
date-format %d/%b/%Y
log-format [%d:%t %^] - %s %^ %^ %m %^ %^ "%U" [Client %h] [Length %^] [Gzip %^] [Sent-to %^] "%u" "%R"

Create the server to use as landing page:
data/nginx/default_host/goaccess.conf

server {
  listen 17890 default;
  listen [::]:17890 default;

  server_name 127.0.0.1;
  access_log /data/logs/default-host_goaccess_access.log combined;
  error_log /data/logs/default-host_goaccess_error.log warn;

  root /var/www/html/goaccess;
  index index.html;

  location / {
    try_files $uri $uri/ =404;
  }
}

Create the landing page
./html/goaccess/index.html

<html>
<body>
<a href="default/">default/</a>
<br />
<a href="proxy/">proxy/</a>
</body>
</html>

In NPM dashboard, create a new proxy

  1. Add a proxy host goaccess.myserver.mydomain to http://npm:17890 (landing page)
  2. Enable WebSocket
  3. Add custom location /default/ws to http://goaccess-default:7890
  4. Add custom location /proxy/ws to http://goaccess-proxy:7890

Secure NPM with Access Lists.
Create a new Access Lists, give it a name. If local network, allow 192.168.1.0/24, if public 0.0.0.0/1.
Use this access in the Proxy Host config.

Nginx with GoAccess

docker-compose.yml

services:
  nginx:
    image: nginx:mainline-alpine
    container_name: nginx
    ports:
      - "127.0.0.1:18080:80" # serves main site
      - "127.0.0.1:18079:18079" # serves goaccess
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./logs:/var/log/nginx

  goaccess:
    image: allinurl/goaccess:1.11
    container_name: goaccess
    ports:
      - "127.0.0.1:7890:7890"
    volumes:
      - ./logs:/logs:ro
      - ./html/goaccess:/report
    command: >
      /logs/access.log
      --log-format=COMBINED
      --output=/report/index.html
      --real-time-html
      --ws-url=wss://goaccess.myserver.mydomain:443/ws
    restart: unless-stopped

nginx/conf.d/goaccess.conf (any chamge in .conf, restart nginx container)

server {
    listen 18079;
    server_name 127.0.0.1;

    absolute_redirect off;
    server_tokens off;

    root /usr/share/nginx/html/goaccess;
    index index.html;
    
    include mime.types;
    
    # HSTS header for enforcing secure connections
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Other headers for security
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";

    location / {
        try_files $uri $uri/ =404;
    }

    location /ws {
        proxy_pass http://goaccess:7890;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;

        proxy_read_timeout 1h;
        proxy_send_timeout 1h;
    }
}

In Nginx Proxy Manager

  1. Add a proxy host goaccess.myserver.mydomain to http://127.0.0.1:18079
  2. Enable WebSocket
  3. Add custom location /ws to http://127.0.0.1:7890
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment