FNMP installation of the laconica server
using nginx and fcgi on FreeBSD

Posted June 26, 2009 by Stefan Caunter and Allan Jude, NearSourceIt
Laconica runs well without apache php; we configure it to listen with the nginx proxy as a front end. The listening spawn-fcgi php engine runs the laconica php scripts. With an optimized database we expect significant performance increases over LAMP deployments. Required:
  • php and mysql
  • laconica
  • nginx
  • spawn-fcgi The FNMP stack is simply Fcgi, Nginx, Mysql and Php. We install laconica in /usr/local/www/laconica. We create a mysql database and grant a user privileges on it (see README for laconica). On FreeBSD, install spawn-fcgi from ports. cd /usr/ports/www/spawn-fcgi make install This installs /usr/local/bin/spawn-fcgi for us. We need it to start on boot, so in /etc/rc.conf type: spawn_fcgi_enable="YES" We need to set in /etc/rc.conf the number of fcgi children to start, increase for high load sites. spawn_fcgi_children="5" The default 5 is not going to do a high load site Then run /usr/local/etc/rc.d/spawn-fcgi start Type this command as root to start it, output looks like this: Starting spawn_fcgi. spawn-fcgi: child spawned successfully: PID: 79643 So php is now listening. We next need to connect it to laconica with nginx. On FreeBSD, install nginx from ports, cd /usr/ports/www/nginx make install edit /etc/rc.conf to say: nginx_enable="YES" and then run /usr/local/etc/rc.d/nginx start Configure nginx to proxy to port 9000 as follows: In /usr/local/etc/nginx/nginx.conf we put a new server container nested inside the http container: This tells nginx where the laconica files are, and where the fastcgi engine is listening. server { listen 80; server_name pbj.ca; access_log logs/laconica.log main; location / { root /usr/local/www/laconica; index index.php; } location \.php$ { client_max_body_size 20m; proxy_set_header Host $host; msie_refresh on; sendfile on; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } } and restart nginx with /usr/local/etc/rc.d/nginx reload check /var/log/nginx-error.log for problems, and that /var/log/laconica.log was created. Connect to the site, it 404s. laconica is not hitting fcgi yet obviously. We need this fuller config (explained below): server { listen 80; server_name pbj.ca; access_log /var/log/nginx-laconia.log main; error_log /var/log/nginx-error.log info; # serve stylesheets as is location /theme { root /usr/local/www/laconica; } location / { try_files $uri $uri/ @laconica; } location @laconica { rewrite ^(.+)$ /index.php?p=$1 last; } # serve stylesheets as is location /theme { root /usr/local/www/laconica; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { root /usr/local/www/laconica; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/www/laconica$fastcgi_script_name; include fastcgi_params; } } Notice the rewriting of the url with try_files and a rewrite rule. Thanks to Maxime Pelletier.

    CSS Style and Rewrite

    We set it in config.php as; $config['site']['theme'] = 'default'; Notice I had to add this to nginx.conf to protect the /theme directory from the rewriting: # serve stylesheets as is location /theme { root /usr/local/www/laconica; } or the rewriting broke stylesheets.

    Email Settings

    Full postfix implementation to control posting will be our next howto. Database errors for adding and inviting users appeared to come from config.php settings. The following code solves this (use values that work for you, this is for a google app setup). $config['mail']['backend'] = 'SMTP'; $config['mail']['notifyfrom'] = '"Laconica At PBJ" '; $config['mail']['domain'] = 'pbj.ca'; $config['mail']['params'] = array ( 'host' => 'smtp.gmail.com', 'port' => '587', 'auth' => true, 'username' => 'stef@pbj.ca', 'password' => 'somethingobvious', 'debug' => false ); We add rewriting for user.example.com to example.com/user in nginx: server { listen 80; server_name *.pbj.ca; location / { if ($host ~* "^([^.]+(\.[^.]+)*)\.pbj.ca$") { set $subd $1; rewrite ^(.+)$ http://pbj.ca/$subd$1 last; } } To use Pelletier's StatsPlugin we add require_once('plugins/StatsPlugin.php'); $stats = new StatsPlugin(); to config.php, copy the StatsPlugin.php file to the plugins subdirectory, and add this rewrite rule to nginx.conf location /stats { rewrite / /index.php?action=stats; }

    Full example of nginx.conf server container for FNMP laconica server:

    server { listen 80; server_name pbj.ca www.pbj.ca; #charset koi8-r; access_log /var/log/nginx-laconia.log main; error_log /var/log/nginx-error.log info; location /js { root /usr/local/www/laconica; } location /stats { #root /usr/local/www/laconica; rewrite / /index.php?action=stats; } location /theme { root /usr/local/www/laconica; } location /avatar { root /usr/local/www/laconica; sendfile on; } location = / { root /usr/local/www/laconica; index index.php; } location / { root /usr/local/www/laconica; try_files $uri $uri/ @laconica; } location @laconica { rewrite ^(.+)$ /index.php?p=$1 last; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/www/nginx-dist; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { root /usr/local/www/laconica; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/www/laconica$fastcgi_script_name; include fastcgi_params; } }