Getting started with NSI
Get NSI
NSI's official repository is hosted on GitHub, and can be downloaded as an archive from there, or by a simple command-line clone from your web server's document directory:
$ git clone https://github.com/nfinit/nsi .
This command will download the NSI engine and demo site into your current directory. If you successfully configure your server in the next step, or you've already prepared, you will be hosting a copy of this site ready to customize!
Prepare your server
Jump to: Configuring Apache, Lighttpd, nginx and othersEvery website needs a server to host it, and the NSI engine is implemented as a Perl CGI script - once the gold standard of the server-side dynamic web, which means it can run on just about anything.
There are, however, some caveats to consider:
- Most web servers out of the box don't execute CGI just anywhere. Older servers especially relegate dynamic scripts to special areas like cgi-bin/. Like modern PHP, Python, JavaScript and other web frameworks, you might need some one-time configuration before deploying NSI.
- Some web servers don't execute CGI at all. CGI was once the gold standard, but some popular modern web servers, particularly nginx and Caddy, have since dropped official support, though you can bring it back with a wrapper like fcgiwrap. We recommend Apache or Lighttpd.
- NSI is tailored to POSIX, or Unix-like environments. It's likely the engine will run on Windows or other platforms, but it hasn't been tested, and a number of features (especially executable script fragments) are likely to break without adaptation. Expect full advertised functionality only under systems like Linux, macOS or real Unix.
- If you're deploying NSI to an especially old target: this engine has thus far been tested as far back as Perl 5.005_03, released in 1999. It might work fine on older versions... or it might not.
If, like us, you've accepted the hurdles of CGI in the 21st century, read on...
Configuring Apache
Apache HTTP Server has long been among the world's most popular web servers, with a rich feature set, good multiplatform support and ready availability. It's often pre-installed on modern Linux and Unix systems, and NSI has been developed and tested on both Apache 1.x and 2.x. Apache can be heavy compared to other servers, but its flexibility and powerful configuration makes us recommend it, especially if you aren't sure what to pick.
Running NSI on Apache requires both mod_cgi and mod_rewrite to be installed and available. These are often included in Apache packages, but rarely enabled. You will likely need to enable them in your Apache configuration file (httpd.conf or apache2.conf) or, on Ubuntu and other Debian family Linux distributions, with the a2enmod command:
a2enmod cgi rewrite
Once you've verified you have the required modules installed and enabled, you'll need to verify Apache's configuration supports CGI execution. If you're setting up NSI on a shared host or other server with AllowOverride All configured, you can simply add these lines to the top of NSI's bundled .htaccess file:
Options +ExecCGI AddHandler cgi-script .cgi DirectoryIndex index.html index.cgi
Alternately, you'll need to edit your Apache server configuration file, for example if your website is in the directory /var/www/html, you can configure it for NSI with this:
<Directory "/var/www/html">
Options +ExecCGI
AllowOverride FileInfo
AddHandler cgi-script .cgi
DirectoryIndex index.html index.cgi
</Directory>
Once you've applied your changes, you'll need to restart Apache to reload its configuration.
Configuring Lighttpd
If Apache is too heavy for you or you don't need all of its features, Lighttpd is an excellent modern alternative, and generally our server of choice.
Like Apache, running NSI on Lighttpd requires optional modules that are still typically bundled in most packages: mod_access and mod_cgi. mod_cgi is often not enabled by default, so you'll likely need to uncomment or add it to your lighttpd.conf file.
Unlike Apache, Lighttpd doesn't support local configuration files like .htaccess, so you'll need to configure the server in lighttpd.conf:
server.modules += ( "mod_access", "mod_cgi" )
cgi.assign = ( ".cgi" => "" )
index-file.names += ( "index.cgi" )
$HTTP["url"] =~ "(^|/)(sys|body)(/|$)|(^|/)\." {
url.access-deny = ( "" )
}
If your lighttpd.conf already has a cgi.assign line present, add ".cgi" => "" to it instead of adding a second line.
Once these changes are applied, restart Lighttpd to re-load the configuration.
Configuring nginx and other servers
As noted in the caveats above, nginx and some other popular modern web servers no longer support CGI at all... out of the box. For servers like these, you'll need to use a wrapper. Instructions here are minimal, as we have not tested this, but this sample nginx.conf using fcgiwrap should work, placed inside of your server { } block in place of the existing location / entry:
location ~ (^|/)(sys|body)(/|$) { return 403; }
location ~ (^|/)\. { return 403; }
location / { index index.html index.cgi; }
location ~ \.cgi$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/fcgiwrap.socket;
}
Keep in mind that the path /run/fcgiwrap.socket can vary by distribution.
Build your first page
The NSI demo site serves as a way to test and exercise most of the engine's core features to ensure your configuration went smoothly. Once everything is in order, blow the pre-loaded content away with:
rm -rf start info intro.html res/logo.gif res/favicon.ico .gitignore README.md
We recommend you leave the .git directory on your site, to allow for easy updates to index.cgi by pulling from GitHub. If you choose this route, be sure to set up a local Git branch before you start working:
$ git checkout -b mysite $ git add -A && git commit -m "Clear NSI demo"
Identify yourself
Before creating a page, give your site a new identity by opening the NSI master configuration in sys/config and setting these values:
- SITE_TITLE: The name of your website
- ORG_NAME: The name of your organization, if you have one, otherwise you can delete or comment this line out.
- ORG_URL: A link to your organization's website, if you have one (or it's elsewhere)
- COPYRIGHT_BEGIN: The earliest date the copyright notice in the footer should display; the year this site was deployed, or earlier if your content came before it. Optionally, you can leave this blank or disable the copyright notice altogether by setting SHOW_COPYRIGHT=0.
With these changes, the site is now yours, and NSI's demo identity has been wiped clean. Values written to a page's sys/config are inheritable, meaning any sub-pages will carry those same values down unless they overwrite them with a sys/config of their own.
Introduce yourself
At this point, navigating to your new site will present you with nothing but a message:
That is, of course, because we just wiped out all of the content. It's now time to add some of your own.
An NSI page's static content is organized into two blocks: intro and body. The former places an HTML block that always appears near the top of the site, while the body's position can vary depending on how you configure special elements like the table of contents and link list, which we'll examine later.
To create an intro for your site, simply create an intro.html in the same directory as index.cgi and start typing; introduce yourself, your project, or any content you wish, in pure unframed HTML. NSI will handle the page structure, style and metadata for you in the background.
Once intro.html is saved, the next time you load your site, the NSI engine will always display it at the top of the page underneath the title. You now have a website!
If you chose to keep the .git directory during the setup process, you can also use Git to track major changes to the site like this, with:
$ git add intro.html $ git commit -m "Created intro"
With git, you can easily version your changes, allowing you to roll back mistakes and reference earlier states of your website at any time.
Describe yourself
You might have noticed at this point that your new site still has no title, and your tab just says something like "Untitled - My Site." You could fix that by setting PAGE_TITLE=My Title in sys/config - your future sub-pages won't inherit it, but that workflow can get annoying after a while, and on top of that, when people find your site on a web search, it won't have a proper description!
NSI's answer to this is the info file, a special file that quickly specifies your page's basic metadata. info is a plaintext file living in the same directory as your index.cgi with the following basic structure:
Page title
Alternate title <-- optional
<-- this empty line must ALWAYS be present!
Page description
The page title describes itself - this line will display on the page header, site navigation, and on search engines. Pick something short but descriptive. If you want your page to show a different title when it's being viewed directly, you can use the optional alternate title, which can allow you to use a longer or different name that only displays on the page itself. The page description can summarize your page to search engines, and also appears as a description if the page appears in another page's table of contents - useful as your site grows.
For our new page, we might do something a little like this:
Home My Site My personal website
When you refresh the page, you'll now see a title "My Site" at the top, while the tab and navigation controls say "Home."
Complete yourself
Now, you have a basic, functioning web page with a header, and introduction, but still no content. You still need a body.
Like an intro, an NSI body is just a block of pure HTML, and can be created in the same way by creating a body.html in the same directory as index.cgi. But large pages especially can get a bit unweildy, and so the real power of the body is its alternate form: fragments. In addition to looking for a body.html next to it, NSI's engine will look for a directory called body/ and any files within it. If anything is present, NSI will compose them together in alphabetical order, allowing you to break up a massive page into smaller, more managable pages covering sections and subsections, and rearrange them at will. An example homepage might have a structure like this:
body/ |-00-projects.html |-10-photos.html \-20-contact.html
Have any ideas? Simply create a body/ directory next to index.cgi and start typing. NSI will compose them altogether into one page on the next load.
...but there's more.
NSI is mainly designed for static websites, but NSI can support dynamic pages, too! Through executable fragments. Executable fragments are just server-side scripts, which NSI can detect if they have a #!shebang in the first line, and will execute inline with the HTML fragments, composing the output into the final page. We wouldn't recommend using NSI to build applications with this functionality... though perhaps you could.
While your site probably won't need to be executing scripts server-side, let's try a simple demo, saved to body/21-uptime:
#!/usr/bin/env sh # title="Live system status" uptime
And making it executable with chmod +x 21-uptime gives us...
Live system status
13:39:22 up 6 days 22:45, 0 users, load average: 0.04, 0.01, 0.00And that's it! We mainly make use of this feature in our own NSI deployments to display live system monitoring data just like this, but you can leverage executable fragments to handle all kinds of server-side dynamic content. Just be careful!
If you're running your website on a Windows server, be aware that executable fragments do not work on Windows. NSI will just dump the script's source verbatim to the page.
At the end of this, you should now have a fully functional single-page NSI website up and running!