/openresty-heroku-example

Example usage of my OpenResty Heroku buildpack

Getting started with the glorious nginx+LuaJIT Web development platform OpenResty is easy with my OpenResty Heroku buildpack! All you need is a file called conf/openresty.conf, as demonstrated in this minimal "hello world"-style app. You don't even need to install OpenResty locally.

To try this example app for yourself:

  1. Sign up for a Heroku account
  2. Get the Heroku Toolbelt (easy to install)
  3. Clone this repository and cd into it:
    $ git clone https://github.com/davidad/openresty-heroku-example; cd openresty-heroku-example
  4. Make sure you are logged in and have a correct SSH public key: $ heroku login && heroku keys:add
  5. Think up a crazy app name that won't already be taken. I'll use example-999 here, but that'll probably be taken, so pick some different numbers or something.
    $ heroku create example-999 --buildpack=https://github.com/davidad/heroku-buildpack-openresty.git
  6. Deploy the app to Heroku.
    $ git push heroku master
  7. Observe that http://example-999.herokuapp.com/ looks like this.
  8. Wonder if you missed something, because that seems too easy.

To run locally, follow the build instructions in this repository, then $ mkdir logs and

$ nginx -p `pwd` -c conf/openresty.conf

Note that you may receive an [alert] about a missing error.log file -- this is OK, and the server should be running unless you also got an [emerg] or other category of fatal error.

This is the source code of the app:

daemon off;
worker_processes 1;
events { worker_connections 1024; }
error_log stderr;

http {
  server {
    default_type text/html;
    include env/heroku-http-port;
    access_log off;

    location / {
      content_by_lua '
        ngx.print("<h1>Hello from Lua!</h1>")
      ';
    }

  }
}

Here's what's going on line-by-line:

  • daemon off;: this is important. nginx likes to run as a daemon, but apparently if a process daemonizes, Heroku assumes it has crashed. So, we ask nginx to not daemonize.
  • worker_processes 1;: we want 1 nginx process. Pretty simple.
  • events { worker_connections 1024; }: Tell you the truth, I don't know what this does. If you remove it, things crash. I assume it's the maximum number of connections each nginx process is supposed to be able to handle.
  • error_log stderr;: Heroku will catch any errors printed here and you can see them on heroku logs
  • http {: nginx can also be a mail server. This indicates that Web-server configuration follows.
  • server {: It can also have more than one Web server (on different ports, for example), so this delimits the scope of a single "server".
  • default_type text/html;: Unless otherwise specified, the server should tell the browser to expect HTML content.
  • include env/heroku-http-port;: Heroku doesn't let apps run on port 80 directly; they're supposed to run on some other random port specified at runtime by the $PORT variable. Port 80 will get "routed" to them magically. My buildpack creates or overwrites this env/heroku-http-port file for you at runtime to say something like listen 22310;. This example includes a conf/env/heroku-http-port reading listen 80; for running locally.
  • access_log off;: You can't access files like this on Heroku anyway, so may as well turn it off.
  • location / {: This will match any request path starting with a / (and they all start with a /). nginx's path matcher is super nice, and you should make good use of it: it'll choose the most specific match (so location /foo can coexist with location /), you can specify exact matches (location = /), and even Perl-compatible regex matches (location ~ /(acceptable|directories|to|serve)/(.*)$).
  • content_by_lua ': content_by_lua is among the OpenResty extensions to nginx. It specifies some Lua code that's going to handle the request.
  • ngx.print("<h1>Hello from Lua!</h1>"): This is pretty self-explanatory, but have a look at this thorough documentation of the ngx API.