In this post I'm going to cover a quick and painless build and package of Nginx compiled with a custom, non-loadble module. That is, it's required to be compiled in and not available from the default packages.

Introduction

Generally speaking, using a repository rather than DIY is prefered due to maintenance, security patches and other sometimes mundane tasks you are unlikely to want to do youreslf.

Building from an existing package provides many benefits over simply compiling from source on a *nix system. Primarily we're thinking about init/upstart/systemd/rsyslog, and unified system specific paths and practices. eg. using /etc/init.d/nginx start vs ./some/path/you/prefixed/nginx, /var/log vs /some/path/you/prefixed/logs, and Debian flavoured sites-enabled symlink directory vs flat configs.

Does the box come back up if it falls down?

YOLO'ing and just deploying a box with a randomly compiled application/version from the internet in /opt or /usr/local or even worse, someone's home directory doesn't cut it in a real production environment, which is probably managed by more than 1 person. Don't be that guy that turned on a box found in 2025 that hasn't been patched, logged, or audited since deployment.

Whatever you do, document, test, automate and log.

The module I'm going to be working with is the rtmp module - Though you could substitute it with any module(s) you require.

This module is now packaged by Dotdeb in nginx-extras, but since I only want this one module, I'll write this tutorial for reference anyway.

Create a clean install VM to work in

Start with a clean VM - I'm using VMWare ESXi, but you could use Virtualbox/Parallels/Fusion, a t2.micro EC2 instance, Docker/LXC or whatever. Just make sure its fresh!

The primary reason for this is to not accidently use a tainted environment to produce false positives or taint your final package.

I'm only provisioning the VM with a single 3.2ghz core with 512mb of ram. Nginx doesn't take that long to compile anyway.

  • Use the Debain 8 netinstall ISO (~250mb), with the same architecture as your target environment. I'm using amd64.
  • Your nearest mirror - mine is iiNet.
  • Use the regular install process, not the graphical one.
  • Paritioning and disksize don't really matter. I'm using a thin provisioned, single partition for / that is only 8GB

Install the base packages

During software selection, only select standard system utilities. SSH server is optional and probably prefered over the VM console. I'm also installing VMWare Tools, but it is totally user preference as the VM is likely to be short lived.

Unlike normal system use, we're going to do everything as root. Generally, this is a terrible idea, but fine for our purpose on a short lived VM. If you're doing this over SSH, be sure you're using PKI or at least a very good password!

The core concept here is that this VM will ONLY be used to perform this one task and will be shutdown / terminated once its complete.

Now to install the build tools and required depenencies for nginx.

root@debian:~# apt-get update && apt-get upgrade
root@debian:~# apt-get install build-essential git mercurial curl libcurl4-openssl-dev \
                               libldap2-dev libossp-uuid-dev libssl-dev libpcre3 libpcre3-dev
root@debian:~# apt-get build-dep nginx

The Dotdeb Apt mirror

You what?

Dotdeb have been fantastic at keeping Nginx (among other packages) up-to-date. They move quickly on security patches as well as features. The reason we are using a 3rd party repo in this case is soley because the build scripts are already going to be near or at the current version of Nginx.

At the time of writing, Dotdeb's latest packaged version of Nginx is 1.8.0, where as Nginx offical release is at 1.9.0. Debian Jessie's stable package is only at 1.6.2-5.

Cloning the repo with Git

We're going to grab Dotdeb's package source from github.

root@debian:~# git clone https://github.com/gplessis/dotdeb-nginx.git
Cloning into 'dotdeb-nginx'...
remote: Counting objects: 5187, done.
remote: Total 5187 (delta 0), reused 0 (delta 0), pack-reused 5187
Receiving objects: 100% (5187/5187), 7.01 MiB | 1.60 MiB/s, done.
Resolving deltas: 100% (1646/1646), done.
Checking connectivity... done.
root@debian:~# cd dotdeb-nginx/

Checking we are on the correct branch

If you are new to source control, or maybe just git, Git uses branches to allow for parallel development of features, versions or patches.

root@debian:~/dotdeb-nginx# git status
On branch jessie
Your branch is up-to-date with 'origin/jessie'.
nothing to commit, working directory clean

As you can see we are on branch jessie. If jessie is not the current branch, you can view available branches and switch to the desired branch

root@debian:~/dotdeb-nginx# git branch -a
* jessie
  remotes/origin/HEAD -> origin/jessie
  remotes/origin/jessie
  remotes/origin/pristine-tar
  remotes/origin/squeeze
  remotes/origin/upstream
  remotes/origin/wheezy

root@debian:~/dotdeb-nginx# git checkout jessie
Branch wheezy set up to track remote branch jessie from origin.
Switched to a new branch 'jessie'

Check again to make sure you're on the correct branch.

root@debian:~/dotdeb-nginx# git status

Grabbing the submodules

Now we've got the base source, we need to grab and update all of the submodules. These are Git submodules, external git source repositories, referenced by the base repository. Most of these are actual modules.

This will retreive the latest source code for each submodule and any submodule they may have (recursively), rather than the exact referenced commit of each, which is the default. This might take a while.

This is going to update submodules to their bleeding edge, you might not want this, as a package maintainer, at this point you want to inspect each and every module you are pulling in.

root@debian:~/dotdeb-nginx# git submodule update --init --recursive --remote

Updating the core Nginx source

Just to be slightly annoying, Nginx's core developers use Mercurial instead of Git. For the life of me, I'll never know why and that could be a blog post all on its own. IMHO it is Git's less intuitive, frustrating cousin.

Cloning the Nginx source

root@debian:~dotdeb-nginx#
root@debian:~# hg clone http://hg.nginx.org/nginx
destination directory: nginx
requesting all changes
adding changesets
adding manifests
adding file changes
added 6145 changesets with 18676 changes to 642 files (+10 heads)
updating to branch default
428 files updated, 0 files merged, 0 files removed, 0 files unresolved
root@debian:~# cd nginx

Switching to the desired release

As with Git, Mercurial also supports Tagging a commit. In this case and in many cases, Tags are used to specify releases.

Listing available tags

Since nginx is a large project with many tags, you may want to pipe it into head since we're only interested in the latest release.

root@debian:~/nginx# hg tags | head -n 5
tip                             6144:d0a84ae2fb48
release-1.9.0                   6135:53d850fe292f
release-1.8.0                   6119:01d52c2b460d
release-1.6.3                   6094:76d66e92c66c
release-1.7.12                  6092:3ef00a71f564

Switching to the latest release tag

As seen above, release-1.9.0 is the latest release tag (luckily for the Git fans, hg alias' update to checkout for some sanity).

root@debian:~/nginx# hg checkout release-1.9.0
11 files updated, 0 files merged, 0 files removed, 0 files unresolved

Shell-Fu: adding the release Nginx source to the Dotdeb package

We're going to remove any directories from the Dotdeb repo that exist in the Nginx source repo, and replace them with the Nginx official ones.

This script is a quite heavy handed, but without knowing a little more about each repo, it will do the job.

root@debian:~/nginx# find . -maxdepth 1 -type d \
    ! -name ".*" \
    ! -name "conf" \
    -exec rm -vrf ../dotdeb-nginx/{} \; \
    -exec cp -av {} ../dotdeb-nginx/ \;

A quick breakdown of the above command Find all directories in the current working directory (offical Nginx source tree), look only 1 level deep, and ignore the conf directory and any directory name beginning with ., (matching ., .. and .hg, removing some unnecessaries). For each found item, remove it from the Dotdeb source (it might not exist anyway) and tell you about it (-v). Then copy each found item recursively and maintain its existing permissions (-a). We're leaving the conf dir out in this case to keep the debian-esque configuration format in favor of the nginx default.

Adding our custom module to the source tree

Luckily for me, the RTMP module is already included as a git submodule. For example sake, I'm going to remove it, then re-add it. If your required module doesnt exist, just follow the steps to add it

Removing the submodule

Removing it from debian/rules (where it matters most)

The actual line we are going to remove is in debian/rules, the line is appended to the configure script pre-build. You can remove it with your favourite editor, obviously nano.

NOTE: We are removing it from nginx-extra, though later will be adding it to nginx-lite

--add-module=$(MODULESDIR)/nginx-rtmp-module \

Removing it with shell-fu

root@debian:~/dotdeb-nginx# sed -i '/nginx-rtmp-module/d' debian/rules

Using (-i) the file debian/rules, find any line that matches the string 'nginx-rtmp-module', and using the d regex flag, delete it. Without the -i parameter the changed content is simply sent to stdout rather than being edited in place.

Removing it from the filesystem and Git (for completeness)

root@debian:~# cd dotdeb-nginx
root@debian:~/dotdeb-nginx# git submodule deinit debian/modules/nginx-rtmp-module
Cleared directory 'debian/modules/nginx-rtmp-module'
Submodule 'debian/modules/nginx-rtmp-module' (git://github.com/arut/nginx-rtmp-module.git) unregistered for path 'debian/modules/nginx-rtmp-module'
root@debian:~/dotdeb-nginx# rmdir debian/modules/nginx-rtmp-module
root@debian:~/dotdeb-nginx# git rm --cached debian/modules/nginx-rtmp-module
root@debian:~/dotdeb-nginx# git rm debian/modules/nginx-rtmp-module
root@debian:~/dotdeb-nginx# rm -rf .git/modules/debian/modules/nginx-rtmp-module

Yes, thats a lot of ways to rm something.

Adding a new module

Adding your module to the filesystem

Assuming you have found your desired module in Git / on github, you can clone it, else, put your source into the right place.

root@debian:~/dotdeb-nginx# git submodule add https://github.com/arut/nginx-rtmp-module.git debian/modules/nginx-rtmp-module
Cloning into 'debian/modules/nginx-rtmp-module'...
remote: Counting objects: 4260, done.
remote: Total 4260 (delta 0), reused 0 (delta 0), pack-reused 4260
Receiving objects: 100% (4260/4260), 3.61 MiB | 1020.00 KiB/s, done.
Resolving deltas: 100% (2414/2414), done.
Checking connectivity... done.

By default, the master branch is checked out, generally, this is the bleeding edge version.

Selecting an exact module version

Just to be sure its working and stable (sure as our faith in devs), we're going to change our module version to the latest release. At the time of writing its version 1.1.7. This step should really be done for EVERY module you plan on compiling, this is just one of the many forgotten, unappreciated tasks performed by our open source package maintainers.

root@debain:~/dotdeb-nginx# cd debian/modules/nginx-rtmp-module
root@debian:~/dotdeb-nginx/debian/modules/nginx-rtmp-module# git tag -l | tail -n 5
v1.1.3
v1.1.4
v1.1.5
v1.1.6
v1.1.7
root@debian:~/dotdeb-nginx/debian/modules/nginx-rtmp-module# git checkout v1.1.7
Note: checking out 'v1.1.7'.
...
HEAD is now at f62a083... fixed compilation with nginx 1.7.11

A nice example of a difference between Mercurial and Git is the order of tags, so we'll use tail instead of head.

Adding your module to debian package rules

Because I'm aiming to package the lightest Nginx installation I can that includes the custom module, I'm going to edit the nginx-light package. Alternatively to this, and preffered for automation and Continuous Integration, would be to add your own set of rules, but thats beyond the scope of this post..

Remember, fewer modules = fewer code paths = fewer lines of code to audit + less attack surface. The fewer modules you choose to use, the more love you will get from your security team.

In debian/rules, you will find the following block.

light_configure_flags := \
    $(common_configure_flags) \
    --with-http_gzip_static_module \
    --without-http_browser_module \
    --without-http_geo_module \
    --without-http_limit_req_module \
    --without-http_limit_conn_module \
    --without-http_memcached_module \
    --without-http_referer_module \
    --without-http_scgi_module \
    --without-http_split_clients_module \
    --without-http_ssi_module \
    --without-http_userid_module \
    --without-http_uwsgi_module \
    --add-module=$(MODULESDIR)/nginx-echo \
    --add-module=$(MODULESDIR)/nginx-x-rid-header \
    --with-ld-opt=-lossp-uuid

You can see it includes the common configure flags (found above this block) and contains extra flags that will be added for the nginx-light package.

Now we're going to add our required module so the bottom of the block looks like this:

--add-module=$(MODULESDIR)/nginx-x-rid-header \
--add-module=$(MODULESDIR)/nginx-rtmp-module \
--with-ld-opt=-lossp-uuid

Bumping the version number and the changelog

The changlelog is something else package maintainers are pedantic about that makes the lives of Sysadmins and DevOps easier. It's best to read the best practices from a GNU/Greybeard.

Here is the changelog entry I have added for this build

nginx (1.9.0-1~drkns+8.1) stable; urgency=medium

  * Imported Upstream version 1.9.0
  * added rtmp module to nginx-light
  * updated nginx-echo to latest release

 -- Tim Noise <tim@drkns.net>  Sun, 10 May 2015 11:53:00 +1000

Note the double space after the email block

Building the packages

Now for some Debian magic, straight to the reference docs to explain this one

This command will clean and rebuild. To rebuild any changes you can use the same command. You can also run debian/rules clean yourself.

root@debian:~/dotdeb-nginx# dpkg-buildpackage -us -uc -b

Beverage break.

Output files are put in ../ so lets take a look at our handywork.

root@debian:~# ls -l
total 41276
drwxr-xr-x 12 root root     4096 May 11 00:44 dotdeb-nginx
drwxr-xr-x  9 root root     4096 May 10 19:08 nginx
-rw-r--r--  1 root root    19666 May 11 00:44 nginx_1.9.0~drkns+8.1_all.deb
-rw-r--r--  1 root root     4573 May 11 00:44 nginx_1.9.0~drkns+8.1_amd64.changes
-rw-r--r--  1 root root    47470 May 11 00:44 nginx-common_1.9.0~drkns+8.1_all.deb
-rw-r--r--  1 root root    31228 May 11 00:44 nginx-doc_1.9.0~drkns+8.1_all.deb
-rw-r--r--  1 root root  3523836 May 11 00:44 nginx-extras_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root 32331030 May 11 00:44 nginx-extras-dbg_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root   386876 May 11 00:44 nginx-full_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root  3022134 May 11 00:44 nginx-full-dbg_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root   264006 May 11 00:44 nginx-light_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root   985044 May 11 00:44 nginx-light-dbg_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root   343110 May 11 00:44 nginx-naxsi_1.9.0~drkns+8.1_amd64.deb
-rw-r--r--  1 root root  1270662 May 11 00:44 nginx-naxsi-dbg_1.9.0~drkns+8.1_amd64.deb

Magic.

lets take a look at our package info.

Beware, dpkg -i is install, dpkg -I is info! Try and use dpkg --install and dpkg --info to prevent mistakes

root@debian:~# dpkg --info nginx-common_1.9.0~drkns+8.1_all.deb
 new debian package, version 2.0.
 size 47464 bytes: control archive=3087 bytes.
     490 bytes,    20 lines      conffiles
     903 bytes,    20 lines      control
     982 bytes,    14 lines      md5sums
    2263 bytes,    69 lines   *  postinst             #!/bin/sh
    1231 bytes,    52 lines   *  postrm               #!/bin/sh
    1096 bytes,    43 lines   *  preinst              #!/bin/sh
 Package: nginx-common
 Source: nginx
 Version: 1.9.0~drkns+8.1
 Architecture: all
 Maintainer: Guillaume Plessis <gui@dotdeb.org>
 Installed-Size: 291
 Depends: lsb-base (>= 3.2-14), init-system-helpers (>= 1.18~), python
 ...
root@debian:~# dpkg --info nginx-light_1.9.0~drkns+8.1_amd64.deb
 new debian package, version 2.0.
 size 264006 bytes: control archive=1641 bytes.
    1223 bytes,    31 lines      control
     266 bytes,     4 lines      md5sums
     773 bytes,    37 lines   *  postinst             #!/bin/sh
     313 bytes,    22 lines   *  prerm                #!/bin/sh
 Package: nginx-light
 Source: nginx
 Version: 1.9.0~drkns+8.1
 Architecture: amd64
 Maintainer: Guillaume Plessis <gui@dotdeb.org>
 Installed-Size: 682
 Depends: nginx-common (= 1.9.0~drkns+8.1), libc6 (>= 2.14), libossp-uuid16, libpcre3 (>= 1:8.35), libssl1.0.0 (>= 1.0.0), zlib1g (>= 1:1.1.4)
 ...

Installing the package

Now we have built our package, installation is easy!

root@debian:~# root@debian:~# dpkg -i nginx-common_1.9.0~drkns+8.1_all.deb nginx-light_1.9.0~drkns+8.1_amd64.deb
Selecting previously unselected package nginx-common.
(Reading database ... 39284 files and directories currently installed.)
Preparing to unpack nginx-common_1.9.0~drkns+8.1_all.deb ...
Unpacking nginx-common (1.9.0~drkns+8.1) ...
Selecting previously unselected package nginx-light.
Preparing to unpack nginx-light_1.9.0~drkns+8.1_amd64.deb ...
Unpacking nginx-light (1.9.0~drkns+8.1) ...
Setting up nginx-common (1.9.0~drkns+8.1) ...
Setting up nginx-light (1.9.0~drkns+8.1) ...
Processing triggers for man-db (2.7.0.2-5) ...
Processing triggers for systemd (215-17) ...

Lets check it out.

root@debian:~# which nginx
/usr/sbin/nginx
root@debian:/etc/nginx# nginx -V
nginx version: nginx/1.9.0
built with OpenSSL 1.0.1k 8 Jan 2015
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_gunzip_module --with-file-aio --with-threads --with-http_spdy_module --with-http_gzip_static_module --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_conn_module --without-http_memcached_module --without-http_referer_module --without-http_scgi_module --without-http_split_clients_module --without-http_ssi_module --without-http_userid_module --without-http_uwsgi_module --add-module=/root/dotdeb-nginx/debian/modules/nginx-echo --add-module=/root/dotdeb-nginx/debian/modules/nginx-rtmp-module --add-module=/root/dotdeb-nginx/debian/modules/nginx-x-rid-header --with-ld-opt=-lossp-uuid

Looks good! Those are our flags.

Making sure its up, starting and stopping

Now we're installed! Let's check to see if its up, the process should have been started by the systemd triggers in the package.

root@debian:~# service nginx status
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
   Active: active (running) since Mon 2015-05-11 01:28:44 AEST; 2min 23s ago
 Main PID: 27880 (nginx)
   CGroup: /system.slice/nginx.service
           ├─27880 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─27881 nginx: worker process

root@debian:~# netstat -tnlp | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      27880/nginx -g daem

root@debian:~# ps aux | grep '[n]ginx'
root     27880  0.0  0.1  33344   748 ?        Ss   01:28   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 27881  0.0  0.7  33708  2776 ?        S    01:28   0:00 nginx: worker process

root@debian:~# curl -v -s 127.0.0.1 1>/dev/null
* Rebuilt URL to: 127.0.0.1/
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.38.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx/1.9.0 is not blacklisted
< Server: nginx/1.9.0
< Date: Sun, 10 May 2015 15:36:44 GMT
< Content-Type: text/html
< Content-Length: 867
< Last-Modified: Sun, 10 May 2015 14:47:31 GMT
< Connection: keep-alive
< ETag: "554f6f83-363"
< Accept-Ranges: bytes
<
{ [data not shown]
* Connection #0 to host 127.0.0.1 left intact

Now lets check those init scripts

root@debian:~# /etc/init.d/nginx restart
[ ok ] Restarting nginx (via systemctl): nginx.service.

Perform the tests above to make sure its back up as expected

root@debian:~# /etc/init.d/nginx stop
[ ok ] Stopping nginx (via systemctl): nginx.service.

Same tests to see if its really down

root@debian:~# /etc/init.d/nginx start
[ ok ] Starting nginx (via systemctl): nginx.service.

Same tests to see if its up again.

Next we reboot the server and make sure its up after it comes back at boot time.

At this point its always a good idea to test directories configured at compile time - We havent changed them, so we will trust both the Nginx developers and Dotdeb maintainers have done that already.

And we're good! Default configured Nginx 1.9.0 packaged up.

Now you can distribute the .deb's as necessary to your target boxes, maybe on your own Apt server, or maybe just with scp.

Removing the package

So maybe its not what you want anymore, or maybe you've built a new version or its been released as you want in the public repo

Remove and keep config

root@debian:~# dpkg -r nginx-common nginx-light
(Reading database ... 39341 files and directories currently installed.)
Removing nginx-light (1.9.0~drkns+8.1) ...
Removing nginx-common (1.9.0~drkns+8.1) ...
Processing triggers for man-db (2.7.0.2-5) ...

This will leave your config in place, aswell as the default docroot - /var/www/html

Purge it with fire!

We can use purge to also remove the config directories, but pay attention to the result

Purge can be done with dpkg -P package-name or dpkg --purge package-name

root@debian:~# dpkg --purge nginx-light nginx-common
(Reading database ... 39341 files and directories currently installed.)
Removing nginx-light (1.9.0~drkns+8.1) ...
Removing nginx-common (1.9.0~drkns+8.1) ...
Purging configuration files for nginx-common (1.9.0~drkns+8.1) ...
dpkg: warning: while removing nginx-common, directory '/var/www/html' not empty so not removed
Processing triggers for man-db (2.7.0.2-5) ...

Now its up to you to remove the docroot, though its likely you will want to back it up first

Configuring Nginx

Now its time to configure the module we initially wanted, RTMP.

Time to add a new config. By default conf.d/*.conf includes are within the http configuration block, the same with site-enabled, I'm going to move the conf.d/*.conf include outside of the http block, then add my new config file in the conf.d directory.

These changes are not added pre-packaging since I don't want to break current compatibility with any existing configs for servers this may be installed on. Any Continuous Integration testing should contain test cases for existing configs.

/etc/nginx/nginx.conf before:

http {
    ...
    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

After:

http {
    ...
    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/sites-enabled/*;
}

include /etc/nginx/conf.d/*.conf;

And now the new contents of /etc/nginx/conf.d/livestream.conf

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
            record off;
        }
    }
}

Now to change our enabled sites.

root@debian:/etc/nginx/sites-enabled# ls -l
total 0
lrwxrwxrwx 1 root root 34 May 11 01:51 default -> /etc/nginx/sites-available/default
root@debian:/etc/nginx/sites-enabled# rm default
root@debian:/etc/nginx/sites-enabled# ls -l
total 0
root@debian:~# /etc/init.d/nginx restart
[ ok ] Restarting nginx (via systemctl): nginx.service.

By removing the default symlink, we've also left Nginx without any default http configuration, meaning it will no longer be listening on port 80 or any port for http at all, instead only listening on our rtmp port, 1935, for the rtmp protocol.

We can verify this by checking netstat

root@debian:~# netstat -tnlp | grep nginx
tcp        0      0 0.0.0.0:1935            0.0.0.0:*               LISTEN      17877/nginx -g daem

Make sure we can hit the port with netcat.

root@debian:~# nc -vv 127.0.0.1 1935
localhost [127.0.0.1] 1935 (?) open
^C sent 0, rcvd 0

Testing the rtmp module actually works is another story, I will be using OBS to push content and VLC to play it back.

There is more details on how to do that in the article that inspired this post.

Final thoughts

Luckily these repositories, packages and source code have all been well maintained, making this process much easier than it could have been. However, if you do go to the effort to package something up, give something back to the open source community you are harnessing and submit your changes, either to the repository, or just on github. You will be suprised at how many people will find it handy. Basically, this is how the open source community works, you take a lot and you give what you can back and we're all better off. You might get flamed once or twice by pedantic cheeto stained neckbeards, but conforming to these high standards is what gives open source quality control, and often times exactly what corporations cannot afford - the time to be meticulous about whitespace, new lines, file names and paths.

Thousands of people eyeballing code and packaging it up, serving it out, fixing the bugs and creating new features; enthusiasts, students and professionals contributing to the global ecosystem.

The pull request that was the result of writing this article

A shitty shell script that practically does the same thing with no comments.

T-shirt

#!/bin/bash -
if [ `whoami` != "root" ]; then echo "be root" && exit; fi
cd && echo "better than skipfish.sh!";
apt-get update && apt-get upgrade
apt-get install build-essential git mercurial curl libcurl4-openssl-dev libldap2-dev libossp-uuid-dev libssl-dev libpcre3 libpcre3-dev
apt-get build-dep nginx
git clone https://github.com/gplessis/dotdeb-nginx.git
cd dotdeb-nginx && git submodule update --init --recursive --remote && cd ..
hg clone http://hg.nginx.org/nginx
cd nginx && hg checkout release-1.9.0
find . -maxdepth 1 -type d ! -name ".*" ! -name "conf" -exec rm -vrf ../dotdeb-nginx/{} \; -exec cp -av {} ../dotdeb-nginx/ \;
cd ~/dotdeb-nginx && dpkg-buildpackage -us -uc -b
dpkg -i ../nginx-common_*deb ../nginx-extras_*deb 
echo "rtmp{server{listen 1935;chunk_size 4096;application live{live on;record off;}}}" >> /etc/nginx/nginx.conf
rm /etc/nginx/sites-enabled/default
echo "done!" && reboot