services: npmplus: container_name: npmplus image: docker.io/zoeyvid/npmplus:latest # or ghcr.io/zoeyvid/npmplus:latest restart: always network_mode: host # ipc: host # required when you want to use the openappsec attachment module # cap_add: # required if you set NGINX_QUIC_BPF to true # - BPF # required if you set NGINX_QUIC_BPF to true # - PERFMON # required if you set NGINX_QUIC_BPF to true # - NET_ADMIN # required if you set NGINX_QUIC_BPF to true # dns: # only set this if you need/want to override the default DNS server # - 192.168.1.1 # default for unifi/opnsense/pfsense # - 192.168.8.1 # default for glinet # - 192.168.178.1 # default for avm/fritz # - 94.140.14.15 # Public AdGuard DNS # - 94.140.15.16 # Public AdGuard DNS # - 2a10:50c0::bad1:ff # Public AdGuard DNS # - 2a10:50c0::bad2:ff # Public AdGuard DNS volumes: - "/opt/npmplus:/data" # - "/var/www:/var/www" # optional, if you want to use NPMplus directly as a webserver for html/php # - "/path/to/old/npm/letsencrypt/folder:/etc/letsencrypt" # Only needed for initial migration from original nginx-proxy-manager to this fork, remove after migration # - "shm-volume:/dev/shm/check-point" # required if you want to use the openappsec attachment module, also enable this volume at the end of this compose.yaml environment: - "TZ=your-timezone" # set timezone, required, set it to one of the values from the "TZ identifier" https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List - "ACME_EMAIL=your-email" # email address to use for acme, currently optional, may be required in the future, so I recommend entering your email here, optional for letsencrypt, but required for zerossl and google public ca # - "ACME_SERVER=https://dv.acme-v02.api.pki.goog/directory (google public ca) / https://acme.zerossl.com/v2/DV90 (zerossl)" # acme server used when requesting/renewing certs using certbot, default: https://acme-v02.api.letsencrypt.org/directory (letsencrypt) # - "ACME_EAB_KID=123456789abcdef" # Key Identifier for External Account Binding for the acme server, not supported by letsencrypt, optional for zerossl (Login on their site => Developer), but required for google public ca: https://cloud.google.com/certificate-manager/docs/public-ca-tutorial?hl=de#request-key-hmac # - "ACME_EAB_HMAC_KEY=123456789abcdef" # HMAC key for External Account Binding for the acme server, not supported by letsencrypt, optional for zerossl (Login on their site => Developer), but required for google public ca: https://cloud.google.com/certificate-manager/docs/public-ca-tutorial?hl=de#request-key-hmac # - "ACME_MUST_STAPLE=true" # enables must-staple, default false, I recommend enabling this if your CA supports it, supported by zerossl, google public ca ignores this, unsupported by letsencrypt (will fail), overrides ACME_OCSP_STAPLING to true # - "ACME_OCSP_STAPLING=true" # enables ocsp stapling, default false, I recommend enabling this if your CA supports it, supported by zerossl and google public ca # - "ACME_PROFILE=shortlived" # sets the profile to be used from the acme server, defaults to "none" (the default profile), supported by letsencrypt (https://letsencrypt.org/docs/profiles), if you use letsencrypt I would recommend the "shortlived" profile, until it is public you should use the "tlsserver" profile, note: both are limited to 25 domains per cert instead of 100 like the "classic" (default) profile # - "ACME_KEY_TYPE=rsa" # which key type to use ecdsa or rsa, default and recommended: ecdsa # - "ACME_SERVER_TLS_VERIFY=false" # enables checking if ACME_SERVER has a valid TLS cert, default and recommended true # - "CUSTOM_OCSP_STAPLING=true" # enables ocsp stapling for custom certs, default false, I recommend enabling this if your custom certs support it # - "PUID=1000" # set user id, needs to be a number greater or equal to 99, or equal to 0, default 0 (root) # - "PGID=1000" # set group id, needs to be a number greater or equal to 99, or equal to 0, default 0 (root), requires non-zero PUID # - "NPM_PORT=82" # Port the NPM UI should be bound to, default 81, change this if you want to run multiple npm instances in network mode host # - "GOA_PORT=92" # Port for goaccess, default 91, change this if you want to run multiple npm with goaccess instances in network mode host # - "IPV4_BINDING=127.0.0.1" # IPv4 address to bind, defaults to all # - "NPM_IPV4_BINDING=127.0.0.1" # IPv4 address to bind for the NPM UI, defaults to all # - "GOA_IPV4_BINDING=127.0.0.1" # IPv4 address to bind for goaccess, defaults to all # - "IPV6_BINDING=[::1]" # IPv6 address to bind, defaults to all # - "NPM_IPV6_BINDING=[::1]" # IPv6 address to bind for the NPM UI, defaults to all # - "GOA_IPV6_BINDING=[::1]" # IPv6 address to bind for goaccess, defaults to all # - "DISABLE_IPV6=true" # fully disables listening on IPv6 and the IPv6 resolver of nginx, overrides IPV6_BINDING/NPM_IPV6_BINDING/GOA_IPV6_BINDING, default false # - "NPM_LISTEN_LOCALHOST=true" # Binds the NPM UI only to localhost (IPv4+IPv6), overrides NPM_IPV4_BINDING/NPM_IPV6_BINDING, default false # - "GOA_LISTEN_LOCALHOST=true" # Binds goaccess only to localhost (IPv4+IPv6), overrides GOA_IPV4_BINDING/GOA_IPV6_BINDING, default false # - "DEFAULT_CERT_ID=1" # ID of cert to use instead of dummycerts, default 0/unset/dummycerts # - "HTTP_PORT=8080" # tcp port to use for http traffic, changing this may break certbot http challenge, default 80 # - "HTTPS_PORT=8443" # udp and tcp port to use for https traffic, changing this may break certbot http challenge, default 443 # - "HTTP3_ALT_SVC_PORT=8443" # please change this if the udp port the clients connect to is not 443, default 443 # - "DISABLE_HTTP=true" # prevents nginx from listening on port 80, default false # - "LISTEN_PROXY_PROTOCOL=true" # should listeners of http(s) hosts (proxy/redirect/dead and default) use proxy protocol instead of http(s)? default false, overrides DISABLE_H3_QUIC to true # - "DISABLE_H3_QUIC=true" # prevents nginx from listening on port 443 udp for default host and all your hosts, this will fully disable HTTP/3 and QUIC, even if you enable it inside the UI, not recommended, default false # - "NGINX_QUIC_BPF=true" # enables nginx's quic_bpf (https://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_bpf), you must also add caps to the NPMplus container (see cap_add of this compose file) to use this, recommended, default false # - "NGINX_LOG_NOT_FOUND=true" # Log 404 errors to the docker logs, unrelated to access logs, default false # - "NGINX_404_REDIRECT=true" # Redirect to / instead of showing a 404 error page, default false # - "NGINX_HSTS_SUBDOMAINS=false" # when enabling security headers, also enable hsts for subdomains, recommended, default true # - "X_FRAME_OPTIONS=deny" # value to use for the X-Frame-Options header when enabling security headers, valid is "deny", "sameorigin" and "none" (means unset), default sameorigin, since this applies to all hosts I recommend instead keeping the default and only change it for hosts which need it using the advanced config and more_set_headers # - "NGINX_DISABLE_PROXY_BUFFERING=true" # Disables the proxy_buffering/proxy_request_buffering options of nginx by default for all hosts, default false, may not work if you use crowdsec/appsec # - "NGINX_WORKER_PROCESSES=8" # value of worker_processes, default and recommended: auto # - "NGINX_WORKER_CONNECTIONS=1024" # value of worker_connections, default: 512 # - "DISABLE_NGINX_BEAUTIFIER=true" # disables nginxbeautifier, useful when it fails parsing non-standard custom/advanced configs, default false # - "FULLCLEAN=true" # Cleans unused config folders, default false # - "LOGROTATE=true" # Enables writing http access logs to /opt/npmplus/nginx/access.log, stream access logs to /opt/npmplus/nginx/stream.log and enables daily logrotation, default false # - "LOGROTATIONS=7" # Set how often the access.log should be rotated until it is deleted, default 3 # - "SKIP_IP_RANGES=false" # Skip fetching/whitelisting ip ranges from cloudflare, default true # - "IPRT=3" # Set how many hours should be between updating ip ranges from aws and cloudflare, default 1, ignored when SKIP_IP_RANGES is true # - "CRT=72" # Set how many hours should be between certbot trying to renew your certs, default 23 # - "GOA=true" # Enables goaccess (and overrides LOGROTATE to true), default false --- if you download the GeoLite2-Country.mmdb, GeoLite2-City.mmdb AND GeoLite2-ASN.mmdb file from MaxMind and place them in /opt/npmplus/goaccess/geoip it will automatically enable GeoIP in goaccess after restarting NPMplus (no need to change GOACLA below), you may also enable the geoipupdate container below (please change the timezone) # - "GOACLA=--agent-list --real-os --double-decode --anonymize-ip --anonymize-level=2 --keep-last=7 --with-output-resolver --no-query-string" # Arguments that should be passed to goaccess, default: --agent-list --real-os --double-decode --anonymize-ip --anonymize-level=1 --keep-last=30 --with-output-resolver --no-query-string # - "PHP82=true" # Activate PHP82, default false, supported, but not recommended, you should prefer to use a dedicated php-fpm container # - "PHP82_APKS=php82-curl php82-openssl" # Add php extensions, also enables PHP82, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.21&repo=community&arch=x86_64&name=php82-*, default none, requires PHP82 # - "PHP83=true" # Activate PHP83, default false, supported, but not recommended, you should prefer to use a dedicated php-fpm container # - "PHP83_APKS=php83-curl php83-openssl" # Add php extensions, also enables PHP83, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.21&repo=community&arch=x86_64&name=php83-*, default none, requires PHP83 # - "PHP84=true" # Activate PHP84, default false, supported, but not recommended, you should prefer to use a dedicated php-fpm container # - "PHP84_APKS=php84-curl php84-openssl" # Add php extensions, also enables PHP84, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.21&repo=community&arch=x86_64&name=php84-*, default none, requires PHP84 # - "PHP_APKS=php-pecl-apcu php-pecl-redis" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.21&repo=community&arch=x86_64&name=php-*, default none, requires PHP82, PHP83 and/or PHP84, not recommended, please use PHP82_APKS, PHP83_APKS or PHP84_APKS # - "INITIAL_ADMIN_EMAIL=" # email to use instead of admin@example.org on first start of NPMplus for the initial user # - "INITIAL_ADMIN_PASSWORD=" # password to use instead of a random password which is logged on first start of NPMplus for the initial user # - "INITIAL_DEFAULT_PAGE=444" # default page to set on first start of NPMplus for the initial user, default congratulations, can be one of: 404, 444, redirect, congratulations or html # - "ENABLE_PRERUN=true" # see readme, default off # - "NGINX_LOAD_OPENAPPSEC_ATTACHMENT_MODULE=true" # loads the openappsec attachment module, you must also set ipc and enable the shm-volume for NPMplus in this compose file, this will fully disable brotli, default false # - "NGINX_LOAD_OPENTELEMETRY_MODULE=true" # loads the opentelemetry module, requires manual configuration, default false # - "NGINX_LOAD_GEOIP2_MODULE=true" # loads the geoip2 module, requires manual configuration, default false # - "NGINX_LOAD_NJS_MODULE=true" # loads the njs module (nginx JavaScript module), requires manual configuration, default false # - "NGINX_LOAD_NTLM_MODULE=true" # loads the ntlm module, requires manual configuration, default false # - "NGINX_LOAD_VHOST_TRAFFIC_STATUS_MODULE=true" # loads the virtual host traffic status module, requires manual configuration, default false # This can be used to enable crowdsec, see README for a guide # crowdsec: # container_name: crowdsec # image: docker.io/crowdsecurity/crowdsec:latest # restart: always # network_mode: bridge # ports: # - "127.0.0.1:7422:7422" # - "127.0.0.1:8080:8080" # environment: # - "TZ=your-timezone" # needs to be changed # - "USE_WAL=true" # - "COLLECTIONS=ZoeyVid/npmplus" # volumes: # - "/opt/crowdsec/conf:/etc/crowdsec" # - "/opt/crowdsec/data:/var/lib/crowdsec/data" # - "/opt/npmplus/nginx:/opt/npmplus/nginx:ro" # - "/opt/openappsec/logs:/opt/openappsec/logs:ro" # only uncomment if you also use the openappsec-agent container # This can be used with GOA=true to keep the geoip database updated, environment variables must be configured # geoipupdate: # container_name: npmplus-geoipupdate # image: ghcr.io/maxmind/geoipupdate:latest # restart: always # network_mode: bridge # environment: # - "TZ=your-timezone" # needs to be changed # - "GEOIPUPDATE_EDITION_IDS=GeoLite2-Country GeoLite2-City GeoLite2-ASN" # - "GEOIPUPDATE_ACCOUNT_ID=" # needs to be changed # - "GEOIPUPDATE_LICENSE_KEY=" # needs to be changed # - "GEOIPUPDATE_FREQUENCY=24" # volumes: # - "/opt/npmplus/goaccess/geoip:/usr/share/GeoIP" # This can be used to run openappsec, you must also set NGINX_LOAD_OPENAPPSEC_ATTACHMENT_MODULE to true and set ipc for NPMplus # openappsec-agent: # container_name: openappsec-agent # image: ghcr.io/openappsec/agent:latest # restart: always # ipc: host # volumes: # - "shm-volume:/dev/shm/check-point" # - "/opt/openappsec/conf:/etc/cp/conf" # - "/opt/openappsec/data:/etc/cp/data" # - "/opt/openappsec/logs:/var/log/nano_agent" # - "/opt/openappsec/localconf:/ext/appsec" # if you don't set AGENT_TOKEN, then please put a local_policy.yaml in the /opt/openappsec/localconf folder before deploying # - "/opt/openappsec/open-appsec-advanced-model.tgz:/advanced-model/open-appsec-advanced-model.tgz" # optional, if you want to use a different model # environment: # - "TZ=your-timezone" # needs to be changed # - "autoPolicyLoad=true" # - "registered_server=NPMplus" # - "user_email=your-email" # optional, from their docs: "This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. [...] If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future." # - "AGENT_TOKEN=" # optional, you can specify an openappsec deployment profile token for connecting to their central webinterface at https://my.openappsec.io, if you leave this commented, make sure to uncomment all other openappsec containers below, see: https://docs.openappsec.io/getting-started/using-the-web-ui-saas/create-a-profile # - "SHARED_STORAGE_HOST=openappsec-shared-storage" # uncomment if you don't set AGENT_TOKEN # - "LEARNING_HOST=openappsec-smartsync" # uncomment if you don't set AGENT_TOKEN # - "TUNING_HOST=openappsec-tuning-svc" # uncomment if you don't set AGENT_TOKEN # command: /cp-nano-agent # uncomment if you don't set AGENT_TOKEN # openappsec-smartsync: # container_name: openappsec-smartsync # image: ghcr.io/openappsec/smartsync:latest # restart: always # environment: # - "TZ=your-timezone" # needs to be changed # - "SHARED_STORAGE_HOST=openappsec-shared-storage" # depends_on: # - openappsec-shared-storage # openappsec-shared-storage: # container_name: openappsec-shared-storage # image: ghcr.io/openappsec/smartsync-shared-files:latest # restart: always # ipc: service:openappsec-agent # user: root # if you do not want to run this container as "root" user you can comment it out and instead run the following command after the deployment: docker exec -u root openappsec-shared-storage chown -R appuser:appuser /db # environment: # - "TZ=your-timezone" # needs to be changed # volumes: # - "/opt/openappsec/storage:/db" # openappsec-tuning-svc: # container_name: openappsec-tuning-svc # image: ghcr.io/openappsec/smartsync-tuning:latest # restart: always # environment: # - "TZ=your-timezone" # needs to be changed # - "SHARED_STORAGE_HOST=openappsec-shared-storage" # - "QUERY_DB_HOST=openappsec-db" # - "QUERY_DB_PASSWORD=password" # replace with something secure, should match POSTGRES_PASSWORD from openappsec-db container # - "QUERY_DB_USER=appsec" # volumes: # - "/opt/openappsec/conf:/etc/cp/conf" # depends_on: # - openappsec-shared-storage # - openappsec-db # openappsec-db: # container_name: openappsec-db # image: postgres:17-alpine # restart: always # environment: # - "TZ=your-timezone" # needs to be changed # - "POSTGRES_PASSWORD=password" # replace with something secure, should match QUERY_DB_PASSWORD from openappsec-tuning-svc container # - "POSTGRES_USER=appsec" # volumes: # - "/opt/openappsec/pgdb:/var/lib/postgresql/data" # This can be used with DISABLE_HTTP=true, to force HTTPS redirects for every host # npmplus-caddy: # container_name: npmplus-caddy # image: docker.io/zoeyvid/npmplus:caddy # restart: always # network_mode: bridge # ports: # - "80:80" # environment: # - "TZ=your-timezone" # volumes: # shm-volume: # driver: local # driver_opts: # type: tmpfs # device: tmpfs