[Solved] Zoneminder and Nginx

Forum for questions and support relating to the 1.29.x releases only.
Locked
Soljia
Posts: 8
Joined: Wed Aug 03, 2016 9:29 pm

[Solved] Zoneminder and Nginx

Post by Soljia »

I have everything working, except one small thing. I can't stream more than one camera at a time via the web interface, it'll show one and all others will not display. I can stream all my cameras on zmNinja at once (assuming because it's uses the API to do such). I've tried looking at the source code to see how the sockets are created in zms, but it's a little bit above me (don't want to invest a whole lot of time to figure out). I noticed the "zms-\n{6}w.sock" always shows up, but only one "zms-\n{6}s.sock" file will show up in /var/run/zm/. Anyone have any ideas? I'm guessing it's probably some mis-configuration with the usage of the fgci-wrapper. Thanks!

Took from https://chiralsoftware.com/content/zone ... s-it-works and https://github.com/pliablepixels/zmNinj ... with-nginx

Error in /var/log/nginx/error.log

Code: Select all

2016/08/01 15:43:48 [error] 22806#0: *190 FastCGI sent in stderr: "PHP message: ERR [socket_sendto( /var/run/zm/zms-693159s.sock ) failed: No such file or directory]" while reading response header from upstream
, client: 66.212.141.202, server: *******************, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "*******************", referre
r: "https://********************/index.php?view=montage&group=0"
/etc/nginx/sites-enables/https.conf

Code: Select all

server {
       listen 443;
       server_name ******************************;

       ssl on;
       ssl_certificate ******************************;
       ssl_certificate_key ******************************;
       keepalive_timeout       60;
       ssl_session_timeout 10m;

       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
       ssl_prefer_server_ciphers on;

    location / {
        root /usr/share/zoneminder/www;
        index index.php;
    }

    location ~ /.*\.php$ {
        root /usr/share/zoneminder/www;

        expires             epoch;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }

    location /cgi-bin {
        gzip off;
        alias /usr/lib/zoneminder/cgi-bin;

        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
    }

    location /api/ {
        alias /usr/share/zoneminder/www/api;
        rewrite ^/api(.+)$ /api/index.php?p=$1 last;
    }

}
Last edited by Soljia on Fri Aug 26, 2016 4:13 pm, edited 1 time in total.
afteroot
Posts: 3
Joined: Fri Aug 05, 2016 2:33 pm

Re: Zoneminder and Nginx

Post by afteroot »

The same problem ( any issues ?
Soljia
Posts: 8
Joined: Wed Aug 03, 2016 9:29 pm

Re: Zoneminder and Nginx

Post by Soljia »

afteroot wrote:The same problem ( any issues ?

What? What does "( any issues ?" mean?
afteroot
Posts: 3
Joined: Fri Aug 05, 2016 2:33 pm

Re: Zoneminder and Nginx

Post by afteroot »

Zoneminder works with nginx now?
without ERR [socket_sendto( /var/run/zm/zms-693159s.sock ) failed: No such file or directory]" while reading response header from upstream ????
afteroot
Posts: 3
Joined: Fri Aug 05, 2016 2:33 pm

Re: Zoneminder and Nginx

Post by afteroot »

Because i have the same error

Code: Select all

2016-08-05 18:52:24.173270	web_php		1336	ERR	socket_sendto( /var/run/zm/zms-207845s.sock ) failed: No such file or directory	includes/functions.php	2371
2016-08-05 18:47:19.349829	web_php		2618	ERR	socket_sendto( /var/run/zm/zms-052771s.sock ) failed: No such file or directory	includes/functions.php	2371
SteveGilvarry
Posts: 494
Joined: Sun Jun 29, 2014 1:12 pm
Location: Melbourne, AU

Re: Zoneminder and Nginx

Post by SteveGilvarry »

Debian Maintainer I believe runs under nginx, some details in the readme and an example conf file. Hope it helps.

https://anonscm.debian.org/cgit/collab- ... DME.Debian
https://anonscm.debian.org/cgit/collab- ... nginx.conf

And check options zms_path matches the cgi path in your config. For example /zm/cgi-bin/nph-zms for debian package.
Production Zoneminder 1.37.x (Living dangerously)
Random Selection of Cameras (Dahua and Hikvision)
Soljia
Posts: 8
Joined: Wed Aug 03, 2016 9:29 pm

Re: Zoneminder and Nginx

Post by Soljia »

You the man Steve!
To avoid problems with feeds from multiple cameras "fcgiwrap" should be
configured to start at least as many processes as there are cameras.
It can be done by adjusting DAEMON_OPTS in "/etc/default/fcgiwrap".
Systemd users may be affected by the following bug:
All you need to do is set the appropriate amount of FCGI_CHILDREN.
/etc/init.d/fcgiwrap

Code: Select all

# FCGI_APP Variables
FCGI_CHILDREN="10"
In case anyone needs it, or wants to reference. Here is my whole /etc/init.d/fcgiwrap file.

Code: Select all

#!/bin/sh
### BEGIN INIT INFO
# Provides:          fcgiwrap
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: FastCGI wrapper
# Description:       Simple server for running CGI applications over FastCGI
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

SPAWN_FCGI="/usr/bin/spawn-fcgi"
DAEMON="/usr/sbin/fcgiwrap"
NAME="fcgiwrap"
DESC="FastCGI wrapper"

PIDFILE="/var/run/$NAME.pid"

test -x $SPAWN_FCGI || exit 0
test -x $DAEMON || exit 0

# FCGI_APP Variables
FCGI_CHILDREN="10"
FCGI_SOCKET="/var/run/$NAME.socket"
FCGI_USER="www-data"
FCGI_GROUP="www-data"
# Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
FCGI_SOCKET_OWNER="www-data"
FCGI_SOCKET_GROUP="www-data"

. /lib/lsb/init-functions

# Default options, these can be overriden by the information
# at /etc/default/$NAME
DAEMON_OPTS="-f"        # By default we redirect STDERR output from executed
                        # CGI through FastCGI, to disable this behaviour set
                        # DAEMON_OPTS to an empty value in the default's file

ENV_VARS="PATH='$PATH'" # We reset the environ for spawn-fcgi, but we use the
                        # contents of this variable as a prefix when calling it
                        # to export some variables (currently just the PATH)
DIETIME=10              # Time to wait for the server to die, in seconds
                        # If this value is set too low you might not
                        # let some servers to die gracefully and
                        # 'restart' will not work
QDIETIME=0.5            # The same as DIETIME, but a lot shorter for the
                        # stop case.

#STARTTIME=2            # Time to wait for the server to start, in seconds
                        # If this value is set each time the server is
                        # started (on start or restart) the script will
                        # stall to try to determine if it is running
                        # If it is not set and the server takes time
                        # to setup a pid file the log message might
                        # be a false positive (says it did not start
                        # when it actually did)

# Include defaults if available
if [ -f /etc/default/$NAME ] ; then
    . /etc/default/$NAME
fi

set -e

running_pid() {
# Check if a given process pid's cmdline matches a given name
    pid=$1
    name=$2
    [ -z "$pid" ] && return 1
    [ ! -d /proc/$pid ] &&  return 1
    cmd="$(cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1)"
    # Is this the expected server
    [ "$cmd" != "$name" ] && return 1
    return 0
}

running() {
# Check if the process is running looking at /proc
# (works for all users)
    # No pidfile, probably no daemon present
    [ ! -f "$PIDFILE" ] && return 1
    PIDS="$(cat "$PIDFILE")"
    for pid in $PIDS; do
      if [ -n "$pid" ]; then
        running_pid $pid $DAEMON && return 0 || true
      fi
    done
    return 1
}

start_server() {
    ARGS="-P $PIDFILE"
    # Adjust NUMBER of processes
    if [ -n "$FCGI_CHILDREN" ]; then
       ARGS="$ARGS -F '$FCGI_CHILDREN'"
    fi
    # Adjust SOCKET or PORT and ADDR
    if [ -n "$FCGI_SOCKET" ]; then
      ARGS="$ARGS -s '$FCGI_SOCKET'"
    elif [ -n "$FCGI_PORT" ]; then
      if [ -n "$FCGI_ADDR" ]; then
        ARGS="$ARGS -a '$FCGI_ADDR'"
      fi
      ARGS="$ARGS -p '$FCGI_PORT'"
    fi
    # Adjust user
    if [ -n "$FCGI_USER" ]; then
      ARGS="$ARGS -u '$FCGI_USER'"
      if [ -n "$FCGI_SOCKET" ]; then
        if [ -n "$FCGI_SOCKET_OWNER" ]; then
          ARGS="$ARGS -U '$FCGI_SOCKET_OWNER'"
        else
          ARGS="$ARGS -U '$FCGI_USER'"
        fi
      fi
    fi
    # Adjust group
    if [ -n "$FCGI_GROUP" ]; then
      ARGS="$ARGS -g '$FCGI_GROUP'"
      if [ -n "$FCGI_SOCKET" ]; then
        if [ -n "$FCGI_SOCKET_GROUP" ]; then
          ARGS="$ARGS -G '$FCGI_SOCKET_GROUP'"
        else
          ARGS="$ARGS -G '$FCGI_GROUP'"
        fi
      fi
    fi
    eval $(echo env -i $ENV_VARS $SPAWN_FCGI $ARGS -- $DAEMON $DAEMON_OPTS) \
        > /dev/null
    errcode="$?"
    return $errcode
}

stop_server() {
    # Force the process to die killing it manually
    [ ! -e "$PIDFILE" ] && return
    PIDS="$(cat "$PIDFILE")"
    for pid in $PIDS; do
      if running_pid $pid $DAEMON; then
        kill -15 $pid
        # Is it really dead?
        sleep "$QDIETIME"s
        if running_pid $pid $DAEMON; then
          kill -9 $pid
          sleep "$QDIETIME"s
          if running_pid $pid $DAEMON; then
              echo "Cannot kill $NAME (pid=$pid)!"
              exit 1
          fi
        fi
      fi
    done
    rm -f "$PIDFILE"
    if [ -n "$FCGI_SOCKET" ]; then
      rm -f "$FCGI_SOCKET"
    fi
}

case "$1" in
  start)
        log_daemon_msg "Starting $DESC" "$NAME"
        # Check if it's running first
        if running ;  then
            log_progress_msg "apparently already running"
            log_end_msg 0
            exit 0
        fi
        if start_server ; then
            # NOTE: Some servers might die some time after they start,
            # this code will detect this issue if STARTTIME is set
            # to a reasonable value
            [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time
            if  running ;  then
                # It's ok, the server started and is running
                log_end_msg 0
            else
                # It is not running after we did start
                log_end_msg 1
            fi
        else
            # Either we could not start it
            log_end_msg 1
        fi
        ;;
  stop|force-stop)
        log_daemon_msg "Stopping $DESC" "$NAME"
        if running ; then
            # Only stop the server if we see it running
            errcode=0
            stop_server || errcode=$?
            log_end_msg $errcode
        else
            # If it's not running don't do anything
            log_progress_msg "apparently not running"
            log_end_msg 0
            exit 0
        fi
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        errcode=0
        stop_server || errcode=$?
        # Wait some sensible amount, some server need this
        [ -n "$DIETIME" ] && sleep $DIETIME
        start_server || errcode=$?
        [ -n "$STARTTIME" ] && sleep $STARTTIME
        running || errcode=$?
        log_end_msg $errcode
        ;;
  status)

        log_daemon_msg "Checking status of $DESC" "$NAME"
        if running ;  then
            log_progress_msg "running"
            log_end_msg 0
        else
            log_progress_msg "apparently not running"
            log_end_msg 1
            exit 1
        fi
        ;;
  # Use this if the daemon cannot reload
  reload)
        log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon"
        log_warning_msg "cannot re-read the config file (use restart)."
        ;;
  *)
        N=/etc/init.d/$NAME
        echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
        exit 1
        ;;
esac

exit 0
chumly
Posts: 1
Joined: Mon Apr 17, 2017 11:10 am

Re: [Solved] Zoneminder and Nginx

Post by chumly »

Apologies for resurrecting and old thread. I am running under nginx and have followed steps from this forum and https://chiralsoftware.com/idea/nginx-u ... zoneminder.

Everything seems fine, the only issue I have is that I cant view all camera's on the montage link, I can view them all on the montage review link which seems weird.

Any suggestions?

error in log:

2017-04-17 12:17:27.580402 web_php 2460 ERR Socket does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/lat ... window-etc for more information.
User avatar
knight-of-ni
Posts: 2404
Joined: Thu Oct 18, 2007 1:55 pm
Location: Shiloh, IL

Re: [Solved] Zoneminder and Nginx

Post by knight-of-ni »

If you can view some, but not all cameras in montage, and the number of cameras you can see is always about 6, then that is a restriction in the web browser. See the faq to address it: http://zoneminder.readthedocs.io/en/lat ... in-firefox

Since you are running nginx, you should also check your php-fpm, fcgi, fcgi-wrap config files. There are parameters for each to set limits on the number of child processes/servers, which restricts the number of simultaneous connections you can have. I forget off hand exactly what the names of the parameters are, but you can find them described in the man page documentation and the comments for each config file.
Visit my blog for ZoneMinder related projects using the Raspberry Pi, Orange Pi, Odroid, and the ESP8266
All of these can be found at https://zoneminder.blogspot.com/
User avatar
knight-of-ni
Posts: 2404
Joined: Thu Oct 18, 2007 1:55 pm
Location: Shiloh, IL

Re: [Solved] Zoneminder and Nginx

Post by knight-of-ni »

thatguy wrote: 6 stream limit by browser can be dealt with. A user on Reddit figured it out. https://www.reddit.com/r/ZoneMinder/com ... re_than_6/

A real fix for that would be JPEG snapshots refreshing on a timer or websocket.
At this point, since chumly hasn't responded yet, it's just pure speculation what the underlying problem might be in this case.

The solution you are referring to was originally posted in our github forum back in Feb of 2015:
https://github.com/ZoneMinder/ZoneMinder/issues/441

That proposed solution might work for some, but it isn't something we can implement upstream because it doesn't work for everyone.

Those of us on the project team unanimously agree that none of the existing workarounds for the browser limitation are real solutions. The fact that it has workarounds have kept us focused on other issues which don't have a workaround. In time, a real fix will be implemented, but at the moment those of us active with the project are tied up with other priorities.
Visit my blog for ZoneMinder related projects using the Raspberry Pi, Orange Pi, Odroid, and the ESP8266
All of these can be found at https://zoneminder.blogspot.com/
Tiver
Posts: 1
Joined: Thu Jul 26, 2018 2:54 pm

Re: [Solved] Zoneminder and Nginx

Post by Tiver »

Details here helped me immensely, but for those that follow, the above FCGI_CHILDREN was not applicable on my Debian 9 system. For others who run into the problem with nginx and only being able to view 1 camera a time, on Debian 9 the solution for me was to create

/etc/default/fcgiwrap

With contents:

Code: Select all

DAEMON_OPTS=-c 10
then restart the fcgiwrap service.

Code: Select all

sudo systemctl restart fcgiwrap
After that I could see 10 fcgiwrap processes. Can adjust the count as needed.
bbunge
Posts: 2951
Joined: Mon Mar 26, 2012 11:40 am
Location: Pennsylvania

Re: [Solved] Zoneminder and Nginx

Post by bbunge »

Thanks! This works on Ubuntu 18.04 and should work also on 16.06 as well!!!
xenDE
Posts: 2
Joined: Thu Feb 09, 2017 11:09 am

Re: [Solved] Zoneminder and Nginx

Post by xenDE »

Hi,

on my debian stretch system, I needed to create missing "/etc/default/fcgiwrap" with 'DAEMON_OPTS="-c 10"' inside and restart with "systemctl restart fcgiwrap"

now I see 10 demons on "systemctl status fcgiwrap.service"

Code: Select all

# systemctl status fcgiwrap.service
● fcgiwrap.service - Simple CGI Server
   Loaded: loaded (/lib/systemd/system/fcgiwrap.service; indirect; vendor preset: enabled)
   Active: active (running) since Tue 2019-08-13 18:16:15 CEST; 2s ago
 Main PID: 28657 (fcgiwrap)
    Tasks: 12 (limit: 4915)
   CGroup: /system.slice/fcgiwrap.service
           ├─28657 /usr/sbin/fcgiwrap -c 10
           ├─28663 /usr/sbin/fcgiwrap -c 10
           ├─28664 /usr/sbin/fcgiwrap -c 10
           ├─28665 /usr/sbin/fcgiwrap -c 10
           ├─28666 /usr/sbin/fcgiwrap -c 10
           ├─28667 /usr/sbin/fcgiwrap -c 10
           ├─28668 /usr/sbin/fcgiwrap -c 10
           ├─28669 /usr/sbin/fcgiwrap -c 10
           ├─28670 /usr/sbin/fcgiwrap -c 10
           ├─28671 /usr/sbin/fcgiwrap -c 10
           ├─28672 /usr/sbin/fcgiwrap -c 10
           └─28691 /usr/lib/zoneminder/cgi-bin/nph-zms
best regards,
daniel
Locked