ruven / iipsrv

iipsrv is an advanced high-performance feature-rich image server for web-based streamed viewing and zooming of ultra high-resolution images.
https://iipimage.sourceforge.io
GNU General Public License v3.0
289 stars 115 forks source link

Service script #164

Open geoffroy-noel-ddh opened 5 years ago

geoffroy-noel-ddh commented 5 years ago

I'm using iipsrv with nginx. Unlike Apache, Nginx won't start the image server, it needs to be started independently. On a linux production server the standard practice is to start a service with a script. E.g. service iipsrv start|stop|status

Is anyone aware of any such script I could reuse? Or is it planned to add this to this repository one day? It would be very useful.

arnocertic commented 5 years ago

Hi, I don't use nginx but I think one solution for you is to use a systemd service. Create if not exists /lib/systemd/system/iipsrv.service which should start the server Create a directory /etc/systemd/nginx.service.wants and make a symlink to /lib/systemd/system/iipsrv.service

So when you start your nginx service, it should also start the iipsrv service

This is just an idea !

geoffroy-noel-ddh commented 5 years ago

Thanks for the tip, I've now checked online how to configure a .service on systemd an it looks simple enough. Thanks again.

ruven commented 5 years ago

How about something like this for iipsrv.service on Debian or Ubuntu? You should change the ExecStart path depending on your iipsrv binary location for other distributions:

[Unit]
Description=IIPImage server
After=network.target
Documentation=man:iipsrv(8)

[Service]
Environment="VERBOSITY=4" "LOGFILE=/var/log/iipsrv.log" "MAX_CVT=5000"
ExecStart=/usr/lib/iipimage-server/iipsrv.fcgi --bind 0.0.0.0:9000 --backlog 1024
Restart=on-failure
geoffroy-noel-ddh commented 5 years ago

Thank you both for your help. I'll try that.

ahankinson commented 5 years ago

I use supervisor which has a built-in fcgi runner. You can use it to start multiple instances of IIP all listening on the same shared socket. This one starts four IIP processes which are shared at TCP port 9000:

[fcgi-program:iipserver]
command=/path/to/fcgi-bin/iipsrv.fcgi
socket=tcp://0.0.0.0:9000
process_name=%(program_name)s_%(process_num)02d
numprocs=4
autostart=true
autorestart=unexpected
redirect_stderr=true
redirect_stdout=true
user=iipuser
group=iipuser
environment=MEMCACHED_SERVERS="127.0.0.1:11211",MEMCACHED_TIMEOUT="604800",JPEG_QUALITY="90",MAX_LAYERS="-1",MAX_CVT="1000",VERBOSITY="2",LOGFILE="/var/log/iip/iipsrv_%(process_num)02d.log"
ruven commented 5 years ago

Thanks @ahankinson, I wasn't aware supervisor had a native FCGI runner. Looks like a nice option for running iipsrv. I'll add a section on this topic to the website documentation.

HansBull commented 4 years ago

Note that iipsrv will also happily comunicate with nginx via a socket:

[Unit]
Description=IIP
After=network.target

[Service]
User=www-data
Group=www-data
RuntimeDirectory=iipsrv
RuntimeDirectoryMode=755
ExecStart=/path/to/iipsrv.fcgi --bind /run/iipsrv/iipsrv.sock

[Install]
WantedBy=multi-user.target

and in the nginx site config file

    location /fcgi-bin/iipsrv.fcgi {
        fastcgi_pass    unix:/run/iipsrv/iipsrv.sock;
        fastcgi_param   PATH_INFO $fastcgi_script_name;
        fastcgi_param   REQUEST_METHOD $request_method;
        fastcgi_param   QUERY_STRING $query_string;
        fastcgi_param   CONTENT_TYPE $content_type;
        fastcgi_param   CONTENT_LENGTH $content_length;
        fastcgi_param   SERVER_PROTOCOL $server_protocol;
        fastcgi_param   REQUEST_URI $request_uri;
        fastcgi_param   HTTPS $https if_not_empty;
    }
lguariento commented 3 years ago

Hello, I'm on a Debian 10, and would like to have IIP running via socket.

My /etc/systemd/system/iipsrv.socket:

[Unit]
Description=iipsrv socket

[Socket]
ListenStream=/run/iipsrv/iipsrv.sock

[Install]
WantedBy=sockets.target

My /etc/systemd/system/iipsrv.service:

[Unit]
Description=IIP
Requires=iipsrv.socket
After=network.target

[Service]
User=myuser
Group=mygroup
RuntimeDirectory=iipsrv
RuntimeDirectoryMode=755
ExecStart=/usr/lib/iipimage-server/iipsrv.fcgi --bind /run/iipsrv/iipsrv.sock

[Install]
WantedBy=multi-user.target

My /etc/nginx/sites-enabled/mysite:

location /fcgi-bin/iipsrv.fcgi {
        fastcgi_pass    unix:/run/iipsrv/iipsrv.sock;
        fastcgi_param   PATH_INFO $fastcgi_script_name;
        fastcgi_param   REQUEST_METHOD $request_method;
        fastcgi_param   QUERY_STRING $query_string;
        fastcgi_param   CONTENT_TYPE $content_type;
        fastcgi_param   CONTENT_LENGTH $content_length;
        fastcgi_param   SERVER_PROTOCOL $server_protocol;
        fastcgi_param   REQUEST_URI $request_uri;
        fastcgi_param   HTTPS $https if_not_empty;
}

Status:

sudo systemctl status iipsrv.service 
● iipsrv.service - IIP
   Loaded: loaded (/etc/systemd/system/iipsrv.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2021-01-03 17:43:48 CET; 4min 55s ago
 Main PID: 1531 (iipsrv.fcgi)
    Tasks: 1 (limit: 2296)
   Memory: 548.0K
   CGroup: /system.slice/iipsrv.service
           └─1531 /usr/lib/iipimage-server/iipsrv.fcgi --bind /run/iipsrv/iipsrv.sock

Jan 03 17:43:48 hms systemd[1]: Started IIP.
sudo systemctl status iipsrv.socket 
● iipsrv.socket - iipsrv socket
   Loaded: loaded (/etc/systemd/system/iipsrv.socket; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2021-01-03 17:34:00 CET; 14min ago
   Listen: /run/iipsrv/iipsrv.sock (Stream)
    Tasks: 0 (limit: 2296)
   Memory: 0B
   CGroup: /system.slice/iipsrv.socket

Jan 03 17:34:00 hms systemd[1]: Listening on iipsrv socket.
hmsadm@hms:~$ sudo journalctl -u iipsrv.socket
-- Logs begin at Sun 2021-01-03 16:33:55 GMT, end at Sun 2021-01-03 17:02:46 GMT. --
Jan 03 16:34:00 hms systemd[1]: Listening on iipsrv socket.
Jan 03 16:57:21 hms systemd[1]: iipsrv.socket: Succeeded.
Jan 03 16:57:21 hms systemd[1]: Closed iipsrv socket.
Jan 03 16:57:21 hms systemd[1]: Stopping iipsrv socket.
Jan 03 16:57:21 hms systemd[1]: Listening on iipsrv socket.
Jan 03 16:57:30 hms systemd[1]: iipsrv.socket: Socket unit configuration has changed while unit has been running, no open socket fi
Jan 03 16:57:31 hms systemd[1]: iipsrv.socket: Succeeded.
Jan 03 16:57:31 hms systemd[1]: Closed iipsrv socket.
Jan 03 16:57:31 hms systemd[1]: Stopping iipsrv socket.
Jan 03 16:57:31 hms systemd[1]: Listening on iipsrv socket.

When I go to /fcgi-bin/iipsrv.fcgi/ I get:

502 Bad Gateway
nginx/1.14.2

What am I doing wrong?

lguariento commented 3 years ago

PS: without socket I can access it. So:

.service file:

ExecStart=/usr/lib/iipimage-server/iipsrv.fcgi --bind 0.0.0.0:9000

and then in the nginx configuration:

location /fcgi-bin/iipsrv.fcgi {
        fastcgi_pass    0.0.0.0:9000;

works fine.

ahankinson commented 3 years ago
[Unit]
Description=iipsrv socket

[Socket]
ListenStream=/run/iipsrv/iipsrv.sock

[Install]
WantedBy=sockets.target

Not sure what you're trying to do with this -- iip should create the socket when it starts. I think you're creating an empty socket with Systemd, and then IIP is getting confused because it already exists.

lguariento commented 3 years ago

Thanks Andrew, I've deleted the socket (I found those instructions in a gunicorn how-to and thought it would apply to this as well. On that occasion it worked). I'm still getting the same error though.

ahankinson commented 3 years ago

If you start IIP on the command line with the socket binding (not using Systemd) what happens? Does that work? Does the socket get created?

lguariento commented 3 years ago

./iipsrv.fcgi --bind unix:/run/iipsrv.sock

or

./iipsrv.fcgi --bind /run/iipsrv.sock

?

The first one gives me a bind/listen: No such file or directory error. The second one returns nothing (it hangs there); then I open another ssh session and look into the /run directory and there's no iipsrv.sock there.

lguariento commented 3 years ago

PS: ./iipsrv.fcgi --bind 0.0.0.0:9000 works just fine.

ahankinson commented 3 years ago

Does your user have permissions to write to the /run/ directory? Looking at the code, the second one should work.

In any case, I would suggest getting it running on the command-line before putting it in systemd.

If you try the second one and it hangs, check to see if it's actually listening on port 9000 (i.e., default behaviour) by running sudo lsof -i -P -n | grep LISTEN. That should show you a list of processes listening on ports.

lguariento commented 3 years ago

I'm running it with sudo just to avoid any permission errors (which it'll throw if I don't have permission).

No, it's not listening to port 9000 if I launch it via /iipsrv.fcgi --bind /run/iipsrv.sock . If you look at that gunicorn/Django tutorial I linked earlier and select Debian version, say, 8, you'll see that the difference is that with Debian 10 (my version) they say you need to create the .socket file. That bit is not in Debian 8. Could it be that something changed in the current Debian version about sockets?

lguariento commented 3 years ago

This is what I get:

hmsadm@hms:~$ sudo ./iipsrv.fcgi --bind /run/iipsrv.sock
hmsadm@hms:~$ sudo ps -A | grep iipsrv
 1044 pts/0    00:00:00 iipsrv.fcgi

hmsadm@hms:~$ sudo lsof -i -P -n | grep LISTEN

[stuff...]
mysqld    677    mysql   34u  IPv6  17218      0t0  TCP *:3306 (LISTEN)
java      725     solr  153u  IPv6  18020      0t0  TCP *:8983 (LISTEN)
[other stuff.... not :9000]
ahankinson commented 3 years ago

Not a solution, but is there a reason why you don't want to run it on :9000 (or any other port?)

lguariento commented 3 years ago

No, no problem at all, I just wanted to find out why the socket connection isn't working. As I said I'm fine with binding it to 0.0.0.0:9000. If there was a remote possibility of a bug or a change needed in the documentation then that might have helped others too (although I appreciate that it's very likely that there's something wrong with my server).

ruven commented 3 years ago

What does it say in the iipsrv log file when you run it from the command line?

./iipsrv.fcgi --bind /run/iipsrv.sock

If it successfully created the socket, you should see a line like this

Running in standalone mode on socket: /run/iipsrv.sock with backlog: 2048

lguariento commented 3 years ago

From http://0pointer.de/blog/projects/socket-activation.html:

Now, let's see how we can enable this service in systemd. For this we have to write two systemd unit files: one describing the socket, the other describing the service. First, here's foobar.socket:

[Socket] ListenStream=/run/foobar.sk

[Install] WantedBy=sockets.target

And here's the matching service file foobar.service:

[Service] ExecStart=/usr/bin/foobard

If we place these two files in /etc/systemd/system we can enable and start them:

systemctl enable foobar.socket systemctl start foobar.socket

etc... buh, it seems like you have to create the .socket file.

See also https://manpages.debian.org/testing/systemd/systemd.socket.5.en.html

lguariento commented 3 years ago

I've put everything in place for one more try with both the .socket and the .service files, and sudo systemctl restart iipsrv.socket writes this in the logs:

<----------------------------------->
Mon Jan  4 15:51:20 2021

IIPImage Server. Version 1.0
*** Ruven Pillay <ruven@users.sourceforge.net> ***

Verbosity level set to 4
Running in standalone mode on socket: /run/iipsrv.sock with backlog: 1024

Setting maximum image cache size to 10MB
Setting filesystem prefix to ''
Setting default JPEG quality to 75
Setting maximum CVT size to 5000
Setting HTTP Cache-Control header to 'max-age=86400'
Setting 3D file sequence name pattern to '_pyr_'
Memcached support enabled. Connected to servers: 'localhost' with timeout 86400

Initialisation Complete.
<----------------------------------->

Still error 502 on the browser though.

ahankinson commented 3 years ago

Usually when I have problems like this, the first thing I blame is SELinux... is that disabled?

lguariento commented 3 years ago

I don't even have the selinux-basics packet installed. Anyway, I'll go with bind 0.0.0.0:9000 and shut up :) .

HansBull commented 3 years ago

Here on Ubuntu 18.04 it works without a .socket file.

Do nginx and iip run under the same user and group?

lguariento commented 3 years ago

@HansBull I can't believe it was something trivial like that. I've put both nginx and iip on the same user:group and now it works like a charm, THANK YOU!

PS: on Debian 10 it doesn't work without a .socket file, I had to create it.