Main  /  Edit  /  History  /   /  Users Area

Configure CppCMS to run with different web servers

Introduction

There are many options to connect CppCMS application to web server:

Please note, this tutorial is provided for running CppCMS based systems in production environment.

It is less friendly for debugging. If you want to debug your application behind web server, use cppcms_run utility which allows you to prepare web server configurations automatically and run web servers themselves.

It allows you to run your web application behind 3 most popular web servers: Apache, Lighttpd and Nginx using FastCGI, SCGI protocols or use them as Reverse HTTP Proxy.

Using HTTP Protocol

CppCMS provides basic implementation of HTTP protocol and thus it can run behind reverse HTTP Proxy or be used in embedded environments. This option is not recommended for use in production environment as internal web server has quite weak performance in serving static files and it is very limited options in comparison to widely used web servers.

Assumptions

In all our examples we assume:

Lighttpd

Lighttpd supports both fastcgi/scgi protocols over unix and tcp/ip sockets. It can start the application for you and use external FastCGI/SCGI application.

Lighttpd, FastCGI

Lighttpd, FastCGI, Start by Web Server

You should enable mod-fastcgi and then use this Configuration file:

fastcgi.server = ( 
  ## The script name of the application
  "/hello" => ((
    ## Command line to run
    "bin-path" => "/opt/app/bin/hello -c /opt/app/etc/config.js",
    "socket" => "/tmp/hello-fcgi-socket",
    ## Important - only one process should start
    "max-procs" => 1, 
    "check-local" => "disable"
  ))
)

CppCMS configuration:

{
  "service" : {
    "api" : "fastcgi",
    "socket" : "stdin" // use server's socket
  }
}

Lighttpd, FastCGI, External Start

You should enable mod-fastcgi and then use this Configuration file:

fastcgi.server = ( 
  ## The script name of the application
  "/hello" => ((
    "socket" => "/tmp/hello-fastcgi-socket",
    ## Important - only one process should start
    "max-procs" => 1, 
    "check-local" => "disable"
  ))
)

CppCMS configuration:

{
  "service" : {
    "api" : "fastcgi",
    "socket" : "/tmp/hello-fastcgi-socket" 
  }
}

Make sure lighttpd has sufficient access rights to read and write to socket '/tmp/hello-fastcgi-socket'.

If you want to use TCP/IP rather then Unix sockets, replace

If you have further trouble check the log '/var/log/lighttpd/error.log'

Lighttpd, SCGI

Lighttpd, SCGI, Start by Web Server (lighttpd >=1.4.23)

You should enable mod-scgi and then use this Configuration file:

scgi.server = ( 
  ## The script name of the application
  "/hello" => ((
    ## Command line to run
    "bin-path" => "/opt/app/bin/hello -c /opt/app/etc/config.js",
    "socket" => "/tmp/hello-fcgi-socket",
    ## Important - only one process should start
    "max-procs" => 1, 
    "check-local" => "disable"
  ))
)

CppCMS configuration:

{
  "service" : {
    "api" : "scgi",
    "socket" : "stdin" // use server's socket
  }
}

Lighttpd, SCGI, External Start

You should enable mod-scgi and then use this Configuration file:

scgi.server = ( 
  ## The script name of the application
  "/hello" => ((
    "socket" => "/tmp/hello-scgi-socket",
    ## Important - only one process should start
    "max-procs" => 1, 
    "check-local" => "disable"
  ))
)

CppCMS configuration:

{
  "service" : {
    "api" : "scgi",
    "socket" : "/tmp/hello-scgi-socket" // use server's socket
  }
}

If you want to use TCP/IP rather then Unix sockets, replace

Apache

Apache, FastCGI

You need to enable at least two modules: mod_fastcgi and mod_alias

For each case we prepare mod_fastcgi configuration file and out config.js.

Note: below we present you an example fastcgi.conf configuration. Be aware that these settings will affect your whole web server. If instead you desire to set these to affect only one specific virtual host, you must place the settings in your virtual host's configuration file (e.g. within /etc/apache2/sites-available on a Debian system). Check the official Apache documentation for details.

Apache, FastCGI, Start by Web Server

Apache configuration:

FastCgiIpcDir /var/lib/apache2/fastcgi
# Usually it is given in fastcgi.conf by default

FastCgiServer /opt/app/bin/hello -initial-env CPPCMS_CONFIG=/opt/app/etc/config.js -socket /tmp/hello-fcgi-socket
# CPPCMS_CONFIG should hold the path to configuration file.
# Note: you can't pass command line parameter
# so you pass the location of configuration file
# via CPPCMS_CONFIG environment variable

FastCGIConfig -maxProcesses 1 -processSlack 1
# This is important - we want apache to use only
# one process as we have cache and many other
# goodies handled by outsefs

ScriptAliasMatch ^/hello(.*)$ /opt/app/bin/hello$1
# We map script "/hello" to our application

AddHandler fastcgi-script /opt/app/bin/hello

CppCMS configuration:

{  
   "service" : {
    "api" : "fastcgi",
    "socket": "stdin" // we use socket given by server
   }
}

Apache, FastCGI, Independent start

Apache configuration:

FastCgiIpcDir /var/lib/apache2/fastcgi
# Usually it is given in fastcgi.conf by default

FastCgiExternalServer /opt/app/bin/hello -socket /tmp/hello-fcgi-socket
# We provide a socket the application listens on.

ScriptAliasMatch ^/hello(.*)$ /opt/app/bin/hello$1
# We map script "/hello" to our application

AddHandler fastcgi-script /opt/app/bin/hello

CppCMS configuration:

{  
   "service" : {
    "api" : "fastcgi",
    "socket": "/tmp/hello-fcgi-socket"
     // Same as in apache config
   }
}

Now you should run the CppCMS application independently as /opt/app/bin/hello -c /opt/app/etc/config.js

If you want to use TCP/IP sockets and not Unix one change

Apache, SCGI

Apache's mod_scgi supports only in-depended/external start and works over TCP/IP sockets, so the configuration is quite simple:

Apache's module configuration:

SCGIMount /hello 127.0.0.1:8081

We pass the script name as mount point and ip:port as point to connect cppcms application.

CppCMS configuration:

{  
   "service" : {
    "api" : "scgi",
    "ip" : "127.0.0.1",
    "port" : 8081
   }
}

Now you should run the CppCMS application independently as /opt/app/bin/hello -c /opt/app/etc/config.js and Apache would connect to it.

Nginx

Nginx supports only FastCGI protocol with external application start.

Note: Nginx's SCGI module is broken as it does not confirm SCGI specifications: it requires rather HTTP response then CGI one. It does not generate SCRIPT_NAME and PATH_INFO variables at all. Don't use it!

Also Nginx's fastcgi module require manual generation of SCRIPT_NAME and PATH_INFO variables.

Nginx, FastCGI

Web Server Configuration under server section:

# Specify UTL to match
location ~ ^/hello.*$ {
    # Socket to communicate
    fastcgi_pass unix:/tmp/hello-fcgi-socket;

    # Setup value of PATH_INFO variable
    fastcgi_split_path_info ^(/hello)((?:/.*))?$;
    fastcgi_param  PATH_INFO       $fastcgi_path_info;

    #
    # You can either use "include fastcgi_params;"
    # or set the variables below manually
    #

    # All supported CGI variables
    fastcgi_param  SCRIPT_NAME     /hello;
    fastcgi_param  QUERY_STRING    $query_string;
    fastcgi_param  REQUEST_METHOD  $request_method;
    fastcgi_param  CONTENT_TYPE    $content_type;
    fastcgi_param  CONTENT_LENGTH  $content_length;

    fastcgi_param  REQUEST_URI     $request_uri;
    fastcgi_param  DOCUMENT_URI    $document_uri;
    fastcgi_param  DOCUMENT_ROOT   $document_root;
    fastcgi_param  SERVER_PROTOCOL $server_protocol;

    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;

    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;

    # end of server variables
}

And the usual CppCMS's config:

{
  "service" : {
    "api" : "fastcgi",
    "socket" : "/tmp/hello-fcgi-socket" 
  }
}

Of course the CppCMS's service should be started independently.

For using TCP/IP protocol replace:

Nginx, SCGI

First of all before you try use SCGI I'd recommend to use FastCGI protocol unless you have very good reasons.

Current (1.0.x nginx version) SCGI protocol implementation for Nginx has a bug:

It does not handle CGI headers as expected so CppCMS should create HTTP headers instead of CGI ones.

Thus service.generate_http_headers option should be set to true

In development version of nginx >= 1.1.17 this bug was fixed, so you don't need the option service.generate_http_headers any more.

Web Server Configuration under server section:

location ~ ^/hello(/.*)$ {
  # Communication protocol
  scgi_pass unix:/tmp/hello-scgi-socket;


  scgi_param  SCRIPT_NAME        /hello;
  scgi_param  PATH_INFO          $1;

  #
  # You can either use "include scgi_params;"
  # or set the variables below manually
  #

  scgi_param  QUERY_STRING       $query_string;
  scgi_param  REQUEST_METHOD     $request_method;
  scgi_param  CONTENT_TYPE       $content_type;
  scgi_param  CONTENT_LENGTH     $content_length;

  scgi_param  REQUEST_URI        $request_uri;
  scgi_param  DOCUMENT_URI       $document_uri;
  scgi_param  DOCUMENT_ROOT      $document_root;
  scgi_param  SERVER_PROTOCOL    $server_protocol;

  scgi_param  GATEWAY_INTERFACE  CGI/1.1;
  scgi_param  SERVER_SOFTWARE    nginx;

  scgi_param  REMOTE_ADDR        $remote_addr;
  scgi_param  REMOTE_PORT        $remote_port;
  scgi_param  SERVER_ADDR        $server_addr;
  scgi_param  SERVER_PORT        $server_port;
  scgi_param  SERVER_NAME        $server_name;

  # end of scgi_params
}

And the special CppCMS's configuration for Nginx.

{
  "service" : {
    "api" : "fastcgi",
    "socket" : "/tmp/hello-fcgi-socket",
    // the option below required for nginx < 1.1.17
    "generate_http_headers" : true 
  }
}

Of course the CppCMS's service should be started independently.

For using TCP/IP protocol replace:

In nginx's configuration replace the line scgi_pass unix:/tmp/hello-fcgi-socket; by scgi_pass 127.0.0.1:8081;

IIS

Before you try to use IIS in front of CppCMS I'd recommend you to chose another web server that is more friendly to web developers who use web server independent API like FastCGI.

Best Approach

Configure CppCMS with some other good web server like Apache or Nginx and forward requests from IIS to it.

HTTP Connectivity

Is probably the most solid option. Forward all requests relevant to the web application the the CppCMS internal web server - use IIS as reverse proxy.

Note: give IIS the job of serving static files. It would likely do it better then CppCMS internal web server.

FastCGI Connectivity

FastCGI - don't use it, it was designed to run PHP and nothing more.

IIS's FastCGI implementation is broken and does not support multi-threaded FastCGI applications.

It also does not provide an option to configure specific port making it even impossible to use CppCMS application with IIS.

SCGI Connectivity

Using with ISAPI SCGI.

There is SCGI ISAPI extension that allows to use external SCGI applications: isapi_scgi

Note: The limitations described below refer to V0.6 of the extension. Starting with version 0.8, isapi_scgi supports both the CGI style (default) response as well non-parsed headers as in 0.6. It is also possible to configure it to pass additional headers without recompilation. See the documentation at the above link for details.

However it (v0.6) has two big limitations:

  1. It does not support real CGI response from the client and expects HTTP response.

    Starting from CppCMS 0.99.10 it is possible to set an option service.generate_http_headers to true. This option tells CppCMS to generate HTTP rather then CGI response headers.

    Using this option it was possible to run successfully CppCMS application with IIS.

  2. It supports only predefined set of HTTP headers so if you will need to get custom headers from for example AJAX responses you'll need to alter isapi_scgi sources.

In order to configure ISAPI extension follow the instructions on this web site.

The CppCMS configuration should look like this:

{
  "service" : {
     "api" : "scgi",
     "ip" : "127.0.0.1",
     "port" : 9999,
     "generate_http_headers" : true
  }
}

Troubleshooting ISAPI SCGI extension.

Note: again, this section is only relevant for isapi_scgi v0.6, not later versions.

First of all you can get sources for isapi_scgi.dll at:

http://twapi.cvs.sourceforge.net/viewvc/twapi/isapi/

Just click download GNU Tarball.

There are several reasons to build it on your own:

If you want to build it with gcc you need to apply following changes:

--- scgi_old.h  2011-08-17 10:48:32.109547500 +0300
+++ scgi.h      2011-08-17 10:50:26.184022000 +0300
@@ -37,3 +37,3 @@
  */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__GNUC__)
 # define COPY_MEMORY(d, s, n) memcpy((d), (s), (n))
@@ -48,3 +48,3 @@
 ZLINK_CREATE_TYPEDEFS(context_t);
-typedef struct context {
+struct context {
 OVERLAPPED ovl;             /* Must be first structure */
@@ -81,3 +81,3 @@
     buffer_t   buf;            /* Data buffer */
-} context_t;
+};

And the you'll be able to build the DLL as:

gcc -O2 -shared buffer.c scgi.c logger.c -lws2_32 -o isapi_scgi.dll

Configuring Other Web Servers

When it comes to configuration of the web servers not mentioned above you should consider following points:

  1. If the web server allows you to start the application you should make sure it starts only a single process.

    Otherwise you may experience problems with cache invalidation, session management and your asynchronous applications would likely not work as they don't share the same process.

  2. Make sure that the FastCGI or SCGI support confirm to the standard. For example: Nginx's SCGI connectors do not parse Status HTTP header and create correct response; IIS's SCGI module does not send HTTP status line at all and expect HTTP like CGI output.

  3. Prefer FastCGI protocol if available as implementations of SCGI usually have lower quality.

  4. Under Microsoft Windows platform, named pipes are not supported, only TCP/IP connections should be used.

    Note: under Windows named pipes are frequently used as replacement of Unix sockets, they are not supported as they have very different behavior.

  5. Make sure that SCRIPT_NAME and PATH_INFO CGI variables are set correctly. In our case, given URL /hello/you SCRIPT_NAME should be /hello and PATH_INFO should be /you

Notes for CppCMS 0.0.x users

CppCMS 0.0.x's web server setup is similar to CppCMS 1.x.x one, as both support FastCGI and SCGI protocols, however the configuration file of the 0.0.x version is quite different.

See:

The protocol is specified as "service.api" and allows options "fastcgi" and "scgi".

However the communication is different.

For example:

  1. FastCGI, TCP/IP

    CppCMS 1.x.x

     {
       "service" : {
          "api" : "fastcgi",
          "ip" : "127.0.0.1",
          "port" : 6000
       }
     }
    

    CppCMS 0.0.x

     service.api = "fastcgi"
     service.socket = "127.0.0.1:6000"
    
  2. SCGI, Unix Socket

    CppCMS 1.x.x

     {
       "service" : {
          "api" : "scgi",
          "socket" : "/tmp/app.sock",
       }
     }
    

    CppCMS 0.0.x

     service.api = "scgi"
     service.socket = "/tmp/app.sock"
    
  3. FastCGI, standard input (started by web server)

    CppCMS 1.x.x

     {
       "service" : {
          "api" : "fastcgi",
          "socket" : "stdin",
       }
     }
    

    CppCMS 0.0.x

     service.api = "fastcgi"
     # service.socket - undefined
    

Thread Safety | Top | How to run the application at the root of the web server

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page



Valid CSS | Valid XHTML 1.0