Enable HTTP/2 in Nginx

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, September 22, 2015

Follow me on Twitter as @mattiasgeniar

As of nginx 1.9.5, there is experimental support for HTTP/2. This article will show you how to enable HTTP/2 support in your Nginx configuration. This can be enabled or disabled per vhost, it does not have to be enabled server-wide.

Warning: you will need at least OpenSSL 1.0.2 if you want to support HTTP/2 on Google Chrome, since they now require ALPN support for HTTP/2. If after this tutorial HTTP/2 isn’t working in Chrome, check your OpenSSL version.

HTTP/2 in Nginx on CentOS / Red Hat

If you’re on Red Hat or CentOS, make sure to enable the mainline repository for nginx. This is considered an experimental release, which could break things.

Here’s what your yum repository should look like.

$ cat /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

If you already had nginx installed, update via yum clean all && yum update nginx or install nginx (if you hadn’t already) by yum install nginx.

HTTP/2 in Nginx on Ubuntu / Debian

If you’re on Debian or Ubuntu, make sure the mainline sources are added to your /etc/apt/sources.list file.

$ cat /etc/apt/sources.list
...
deb http://nginx.org/packages/mainline/debian/ codename nginx
deb-src http://nginx.org/packages/mainline/debian/ codename nginx

Next, update your nginx installation with apt-get clean && apt-get install nginx.

HTTP/2 on Nginx requires at least 1.9.5

Verify that your nginx version is at least 1.9.5.

$ nginx -v
nginx version: nginx/1.9.5

Anything lower will not yet have HTTP/2 support and you’ll be greeted with the following error message.

nginx: [emerg] invalid parameter "http2" in /etc/nginx/conf.d/ssl.conf:2
nginx: configuration file /etc/nginx/nginx.conf test failed

Enable HTTP/2 in Nginx

Now, in order to enable HTTP/2, you need to have an SSL/TLS enabled vhost. In other words: you need an SSL certificate, as HTTP/2 is only implemented over TLS.

Enabling HTTP/2 is just as simple as enabling SPDY, it’s a flag in the listen directive in your virtual host config.

Add the http2 keywords to your virtualhost configuration.

server {
  listen        443 ssl http2;
  server_name   your.fqdn.tld;

  access_log    access.log main;
  error_log     error.log error;

  # Start the SSL configurations
  ssl                   on;
  ssl_certificate       /etc/nginx/conf.d/certificate.crt;
  ssl_certificate_key   /etc/nginx/conf.d/certificate.key;

  # Add any other TLS optimisations like strong ciphers etc ... 
  # ...
}

Enabling really is this simple, just change your current ssl-line from this:

server {
  listen        443 ssl;
  ...
}

to this:

server {
  listen        443 ssl http2;
  ...
}

Please note: you can not mix SPDY and HTTP/2. If you try to enable both, you’ll get an error on startup of nginx.

nginx: [warn] invalid parameter "spdy": ngx_http_spdy_module was superseded by ngx_http_v2_module in /etc/nginx/conf.d/vhost.conf:12

If you just want to play around with HTTP/2, you can create a self-signed SSL certificate and implement that in your vhost.

Lack of server side push

As of yet, Nginx does not support one of the most powerful features of HTTP/2: server side push. Only nghttp2 seems to support it at this time.

But HTTP/2 brings a lot of improvements to the table, like TCP multiplexing, header compression, less domain sharding, … that make it a worthwhile upgrade already.

Testing HTTP/2

There are already a couple of HTTP/1.1 vs HTTP2 benchmarks out there, but the best test is the one you can do yourself.

Since Nginx now makes it really easy to enable HTTP/2, we activated it on our corporate website as well: www.nucleus.be. Want test HTTP/2? Just browse to nucleus.be.

If you’re curious to know how you can detect if you’re on HTTP/1.1 or HTTP2, you can view the HTTP/2 protocol in your Chrome Inspector.

More reading material on HTTP/2

Want to know more about HTTP/2? Here are a few suggestions:



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.