Manage multiple web sites, with CGI and WebSockets

 

Syntax:

 

jsite [ ip . . . ] [ -f folder ] [ -u user ] [ -g group ] [ -t | -q | -a | -h ] where: ip = a list of IP addresses on which the nginx server is to listen for connections (IPv6 in square brackets). A colon and a port number may be appended (default :80 and :443). If omitted nginx listens on all interfaces. If site.crt and site.key files are present in the home directory, nginx listens for HTTPS connections on :443. -f = folder for JSITE configuration and run files. Must be within the /sss folder and defaults to /sss/jsite. (The /sss folder is used by several system utilities and is automatically created on tmpfs if not already present). -u = user name for nginx worker processes, defaults to www-data. -g = group name for nginx worker processes, defaults to -u value. -t = test generated nginx configuration and immediately exit. -q = quit all running servers (graceful termination). -a = alias all sites to 127.0.0.1 in /etc/hosts (lcl.example.com). -h = display this help text and exit.

Synopsis:

This program invokes and manages the nginx web server, after first forking multiple copies of itself, each becoming a CGI, WebSocket (WSX) or some other backend server for nginx. It is intended as the primary web service for multiple domains on a single server host. It also runs well on workstations and portables, where it provides a graphical user interface for locally installed web-based programs. In this environment, it further serves as a powerful web development tool, before fully tested content is transferred to a production server.

The nginx server delivers static HTML content over the localhost, LAN and WAN interfaces. It also acts as a reverse proxy for the CGI and WSX backend servers provided by jsite. All of this is configured automatically by jsite, without any special administrator actions. All configuration and run time files are stored in the restricted /sss/ system directory structure, which is shared by several other services, and is automatically created on temporary storage (tmpfs).

If the nginx server is already running, a new configuration is created and SIGHUP is sent to the nginx server, causing it to restart with the new configuration. The -t option may also be given to test the configuration and immediately exit, without starting, stopping or restarting any servers. The -q option is used to gracefully terminate all running servers started by jsite. The -h option displays the "help" summary, above, and exits without doing anything else.

For auto-configuration jsite expects each web site to have its own home directory, with a site sub-directory containing the static HTML content to be served by nginx to connecting browsers (e.g. /home/example.com/site/). Standard Unix tools can be used to create a user and group for example.com and, hence, the site's home directory. Alternatively, a home directory can be created manually, owned by an existing user and group. Either way, any member of the group can create and maintain the site folder and its content, using any of the many common editing tools (including some that run in a web browser). The main nginx server is configured with the site sub-folder as the document root for each domain (which may be sub-directed in any way the developer chooses). It cannot directly serve any content outside of site. However, symbolic links within site may be used to share pages among multiple sites.

Any CGI or WSX programs must be kept in a separate site.bin folder (/home/example.com/site.bin/) which is outside the site folder and is not included anywhere in the nginx configuration. Thus, server side program code is not directly available to nginx or client browsers. HTTP or HTTPS requests beginning with example.com/cgi/program/ or example.com/wsx/program/ are reverse proxied to the jsite CGI or WSX backend servers, which execute the referenced program from site.bin as a new process. All such programs are executed with the user and group of the site's home directory and therefore have write access to the site's entire home directory. The nginx server does not, because it does not run as a member of the web site's group. Thus, all data uploads to a given site will fail unless they go through a CGI or WSX program specifically authorized by its presence in the site.bin folder.

The protocol for writing CGI programs is described on a separate CGI programming page. The protocol for creating WSX programs is described on the WebSocket Programming page. Although slightly more complicated, WSX programs are many times faster than CGI, AJAX or PHP, because there is no need to transmit a complete set of headers with each half duplex message to or from the server. They are also far more flexible, because client and server side JavaScript programs can communicate in full duplex mode over the socket, with only simple message framing on top of the underlying connection. Therefore, all new applications of any significance should use the WSX interface. New CGI programs would still be appropriate for simple form submission, or to initiate other server actions from a single link click.

For nginx, each site configuration includes the wild card domains *.example.com and example.* — allowing the same content to be served over www.example.com or example.net as well as example.com itself. Note, however, that a separate home directory for a specific domain always overrides any wild card (i.e. /home/example.net/ is checked separately from /home/example.com). It is also possible for site folders (or their contents) to be links to the site folder of another domain, again allowing sharing of the same content from multiple domain names. Additionally, each configuration points its nginx log files to site.access.log and site.error.log within the domain's home directory. To suppress logging, these files may be links to /dev/null. Or, they may be links to shared log files stored elsewhere.

Per-user pages can be served, for one or more domains, by creating whom/ and whom.bin/ folders in a local user's own home directory. For example, if local user "fred" creates his own whom folder, it can be accessed via http://example.com/=fred. With our penchant for puns, we call these "whom pages". They do not require a separate domain for each user and can be used on home and small business sites to support private social networking applications.

For any domain, the generated configuration may be completely or partially overridden by a site.cfg file in the home directory. If this file begins with the keyword server, the contents of the file completely replace the jsite generated nginx configuration for that domain. In this case, the file must contain one or more complete and valid server blocks. Otherwise, the file may contain one or more nginx configuration lines to be inserted at the end of the jsite generated server block for the domain. For example, server side includes (SSI) may be turned on with nothing more than an "ssi on;" line. Proxying fastCGI (and PHP) is a little more complicated and requires a complete location block, but most nginx variables are already set with the correct values. The following block is usually sufficient to proxy PHP requests (via fastCGI) to .php scripts stored in the site.bin folder:

location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; try_files $document_root$fastcgi_script_name = 404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; }

Encrypted HTTPS requests can be serviced by including the site's public SSL/TLS certificate and private key in site.crt and site.key within the home directory but outside the site folder (they may be links to the actual files). The network security page shows how to create certificates and keys. It also provides important information for improving online security.

The ip address list has a few quirks, designed to provide greater flexibility in address and port configuration. If the list is completely omitted, nginx is configured to listen on port 80 of all interfaces (both IPv4 and IPv6) for all home directories with a site sub-directory. In addition, it listens on port 443 (HTTPS) for all domains with SSL/TLS certificates, on all interfaces, including the local host (127.0.0.1 or [::1]). So, by default, "secure" sites can be reached by either HTTP or HTTPS requests, even on the local host. This is also the case if the list consists of just the wildcard addresses (*) and/or [::]. It is also true for specific interface addresses without a port number (or with the wildcard port). This is generally desirable to ease automatic transitions between HTTP and HTTPS.

The default behavior can be modified by using specific addresses and port numbers. In particular, nginx does not listen for HTTPS connections on port :80 or on the reserved addresses localhost, 127.0.0.1 or [::1]. If the domain has an SSL/TLS certificate, it does not listen for HTTP (port :80) requests unless the port number is omitted (or the wildcard). For example, localhost 8.9.10.11:* suppresses HTTPS on the local host but listens for both HTTP and HTTPS on the external interface. On the other hand, 8.9.10.11:443 listens for only HTTPS requests, only on that external interface.

On most Linux systems the jsite server can be easily started at boot time by adding a line to the /etc/rc.local file, immediately after the echo line which registers JSUS with the binfmt file system. For example, /usr/bin/jsite 127.0.0.1 -a would start the server on just the localhost interface, after first aliasing all web sites to this address in the /etc/hosts file. Then, local sites can be accessed by pointing a browser to the http://lcl.example.com sub-domain, with no need for any DNS setup.

Finally, jsite creates a default site on all specified interfaces for the same domain as the host name of the computer on which it is running. The document root of this site is set to the online documentation for JSUS (/usr/share/doc/jsus/). Thus, any requests for an unidentified domain, or the computer's host-name, will display this manual, as installed with JSUS. Which is, perhaps, how you got here . . .

 

See also:

CGI programming Web Socket Programming