<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>David Beath (Posts about hosting)</title><link>https://davidbeath.com/</link><description></description><atom:link href="https://davidbeath.com/categories/hosting.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Tue, 28 Jul 2026 20:04:05 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Nginx and ELB Proxy Protocol Forwarding</title><link>https://davidbeath.com/posts/elb-nginx-proxy-forwarding/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;Recently I noticed that an application I'm hosting on &lt;a href="https://aws.amazon.com/elasticbeanstalk/"&gt;AWS Elastic Beanstalk&lt;/a&gt; wasn't logging the Client IP Address of my users. After a lot of digging I found the issue was to do with the configuration of the &lt;a href="https://www.nginx.com/resources/wiki/"&gt;Nginx&lt;/a&gt; servers running on the &lt;a href="https://aws.amazon.com/ec2/"&gt;EC2&lt;/a&gt; instances and in my application's &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; container, and in the TCP passthrough configuration of the &lt;a href="https://aws.amazon.com/elasticloadbalancing/"&gt;Elastic Load Balancer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So here's a quick post about my particular setup and the configuration I used to fix this issue of Client IP Addresses not being forwarded.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;h3&gt;Elastic Beanstalk Setup&lt;/h3&gt;
&lt;p&gt;In a little more detail, my setup consists of an application hosted within a Docker container running on EC2 instances configured by Elastic Beanstalk, which sit behind an Elastic Load Balancer (ELB). Because of issues with Certificate support in ELB, I'm not using AWS's Certificate Manager or using the built-in SSL termination in ELB, but instead using TCP passthrough on the ELB, and using a custom Nginx configuration on each EC2 instance to terminate the SSL connection. The Docker container on each instance also has it's own Nginx configuration, which proxies the application server, in my case &lt;a href="https://uwsgi-docs.readthedocs.io/en/latest/"&gt;UWSGI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The steps that a request takes to get to the application are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;User makes an HTTPS request.&lt;/li&gt;
&lt;li&gt;ELB uses TCP passthrough to pass the encrypted request to an EC2 instance.&lt;/li&gt;
&lt;li&gt;Nginx in EC2 decrypts the HTTPS request and passes the HTTP to it's Docker container.&lt;/li&gt;
&lt;li&gt;The Nginx server on Docker proxies the request to UWSGI.&lt;/li&gt;
&lt;li&gt;The application hosted by UWSGI handles the request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In all, the parts that you need to configure to forward the Client IP Address are the TCP passthrough on ELB and each of the two Nginx servers.&lt;/p&gt;
&lt;h3&gt;Proxy Protocol&lt;/h3&gt;
&lt;p&gt;The first problem is that if you're using a TCP load balancer to pass through the request, the load balancer will not add an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For"&gt;&lt;em&gt;X-Forwarded-For&lt;/em&gt;&lt;/a&gt; header, and so the downstream Nginx server will only see the IP Address of the load balancer. The problem and part of the solution is &lt;a href="https://chrislea.com/2014/03/20/using-proxy-protocol-nginx/"&gt;described in better detail here&lt;/a&gt;. The linked solution is a little different from what I'm going to show below, because I'm proxying the request another hop down the line, but please read the link to better understand what's going on.&lt;/p&gt;
&lt;p&gt;The first step is to enable Proxy Protocol support on the Elastic Load Balancer. AWS has a &lt;a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html"&gt;good tutorial&lt;/a&gt; on how to do that.&lt;/p&gt;
&lt;p&gt;Once the ELB has Proxy Protocol support enabled, you can configure the Nginx server on the EC2 instances. The relevant parts of the configuration look something like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;log_format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;elb_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;$proxy_protocol_addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$remote_user'&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="s"&gt;'[&lt;/span&gt;&lt;span class="nv"&gt;$time_local]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$request"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$body_bytes_sent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="nv"&gt;$http_referer"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$http_user_agent"'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;http2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;proxy_protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;set_real_ip_from&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;172&lt;/span&gt;&lt;span class="s"&gt;.31.0.0/20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;real_ip_header&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s"&gt;proxy_protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;access_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/elb-access.log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;elb_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# SSL Certificate settings go here.&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_pass&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;https://docker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_http_version&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Connection&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Host&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;X-Real-IP&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nv"&gt;$proxy_protocol_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;$proxy_protocol_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here's what's happening in the above config:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;em&gt;listen&lt;/em&gt; directive now has &lt;em&gt;proxy_protocol&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;set_real_ip_from&lt;/em&gt; tells Nginx the real CIDR range of addresses that the ELB is using.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;real_ip_header&lt;/em&gt; tells us that we're using the &lt;em&gt;proxy_protocol&lt;/em&gt; value to access the client headers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;X-Real-IP&lt;/em&gt; and &lt;em&gt;X-Forwarded-For&lt;/em&gt; use the &lt;em&gt;$proxy_protocal_addr&lt;/em&gt;, which is the client IP information taken from the proxy protocol.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;elb_log&lt;/em&gt; format is now using the &lt;em&gt;$proxy_protocal_addr&lt;/em&gt; for the client IP.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Also note that the &lt;em&gt;listen&lt;/em&gt; directive can support both &lt;em&gt;http2&lt;/em&gt; and &lt;em&gt;proxy_protocol&lt;/em&gt;, so if your version of Nginx supports &lt;a href="https://hpbn.co/http2/"&gt;HTTP/2&lt;/a&gt; then you can enable that just fine. However, the &lt;em&gt;proxy_http_version&lt;/em&gt; directive in this case is still &lt;em&gt;1.1&lt;/em&gt;, as it &lt;a href="https://mailman.nginx.org/pipermail/nginx/2015-December/049445.html"&gt;doesn't make sense&lt;/a&gt; to use HTTP/2 for proxy backends.&lt;/p&gt;
&lt;p&gt;If you deployed the above config, you should now see that Nginx server on the EC2 instance is now logging the correct client IP Address.&lt;/p&gt;
&lt;h3&gt;Multiple Nginx Proxies&lt;/h3&gt;
&lt;p&gt;Now that we have the Nginx server on the EC2 instance receiving the correct Client IP from the Load Balancer, we need to foward that IP on to the Nginx server in the Docker container.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;X-Forwarded-For&lt;/em&gt; and &lt;em&gt;X-Real-IP&lt;/em&gt; directives in the above config will properly forward the Client IP from the EC2 instance's Nginx server. However, Nginx appends each proxy's IP address to the &lt;em&gt;X-Forwarded-For&lt;/em&gt; header, as described in more detail &lt;a href="https://distinctplace.com/2014/04/23/story-behind-x-forwarded-for-and-x-real-ip-headers/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The solution to this is in the last Nginx proxy configuration is to include the IP address ranges of all previous known proxies in the &lt;em&gt;set_real_ip_from&lt;/em&gt; directive. You can then set the &lt;em&gt;real_ip_header&lt;/em&gt; directive to &lt;em&gt;X-Forwarded-For&lt;/em&gt;. The final piece is to set &lt;em&gt;real_ip_recursive&lt;/em&gt; to &lt;em&gt;on&lt;/em&gt;, which will return the leftmost (original) IP instead of the rightmost (most recent) IP from the &lt;em&gt;X-Forwarded-For&lt;/em&gt; header.&lt;/p&gt;
&lt;p&gt;My Nginx configuration for the Docker container now looks like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;upstream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;unix:///tmp/uwsgi.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;set_real_ip_from&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;172&lt;/span&gt;&lt;span class="s"&gt;.31.0.0/20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# IP of the ELB&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;set_real_ip_from&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;172&lt;/span&gt;&lt;span class="s"&gt;.17.0.0/20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# IP of the EC2 instance&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;real_ip_header&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;real_ip_recursive&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;uwsgi_pass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;app&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;uwsgi_params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that I've included the IP ranges of both the ELB and the EC2 instance. With a config similar to this you should now see the Nginx instance in the Docker container log the correct Client IP, and pass that IP through to your application.&lt;/p&gt;</description><category>hosting</category><category>IT</category><category>Nginx</category><category>tutorial</category><category>Web</category><guid>https://davidbeath.com/posts/elb-nginx-proxy-forwarding/</guid><pubDate>Mon, 17 Apr 2017 10:35:06 GMT</pubDate></item><item><title>Installing Tiny Tiny RSS from scratch</title><link>https://davidbeath.com/posts/installing-tiny-tiny-rss-from-scratch/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;Considering that a couple of times now I've been a proponent of using an RSS reader, I figured it was time I wrote a tutorial on how to install &lt;a href="https://tt-rss.org/"&gt;Tiny Tiny RSS&lt;/a&gt;, using &lt;a href="https://nginx.org/"&gt;Nginx&lt;/a&gt; as the server and &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; for the database. While as with any piece of software there are a number of tutorials and guides already out there, I've found that none of them provided a complete instruction set that didn't have me running into and searching for solutions to multiple errors. To that end, this tutorial aims to both provide as complete a set of fool-proof instructions as I can make, both for newbies to self-hosting, and simply as a reference for my future self should I need to do this again.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;This set of instructions assumes that you're running a Debian based Linux distro. I've tested this setup on a clean Ubuntu Server 12.04 virtual machine, and the settings are roughly the same as I'm using on my Debian server. It's assumed that you either know how to set up a server already, or are capable of reading a tutorial to do so (If not, then why are you reading this? Go use &lt;a href="https://cloud.feedly.com/"&gt;Feedly&lt;/a&gt;). There are some very good tutorials at &lt;a href="https://www.digitalocean.com/community/"&gt;Digital Ocean&lt;/a&gt; and &lt;a href="https://library.linode.com/"&gt;Linode&lt;/a&gt;, and I'd recommend either of them for hosting purposes.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;On to the install. While not strictly necessary, the first thing I recommend is to make sure that your server is using the correct time, so install ntp to keep the system clock updated.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ntp
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For most of the commands in this tutorial you'll need super user privileges, so you can either run them as root (not recommended) or use &lt;code&gt;sudo&lt;/code&gt; like I've used in this tutorial.
You'll also need to edit a bunch of files in a text editor. I've used &lt;code&gt;nano&lt;/code&gt; for this tutorial because it's easier to use and you can just copy the commands straight, but I usually use &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;PHP&lt;/h3&gt;
&lt;p&gt;Unfortunately, despite the fact that &lt;a href="https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/"&gt;PHP sucks&lt;/a&gt; (seriously, read the article, even if you disagree it's an interesting read), Tiny Tiny RSS is built with PHP. However, just because a language sucks doesn't mean that programs written in it necessarily have to, and tt-rss is the best of the self-hosted RSS readers. Still, that means you're going to have to install PHP, and get it working nicely with Nginx.&lt;/p&gt;
&lt;p&gt;Install PHP 5 and the components necessary to get it playing nicely with everything else.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;php5&lt;span class="w"&gt; &lt;/span&gt;php5-fpm&lt;span class="w"&gt; &lt;/span&gt;php5-curl&lt;span class="w"&gt; &lt;/span&gt;php5-pgsql&lt;span class="w"&gt; &lt;/span&gt;php5-gd&lt;span class="w"&gt; &lt;/span&gt;php5-mcrypt&lt;span class="w"&gt; &lt;/span&gt;php5-cli
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There's one line in php.ini you'll need to change, which will prevent a possible &lt;a href="https://wiki.nginx.org/Pitfalls#Passing_Every_.7E_.5C.php.24_request_to_to_PHP"&gt;security issue&lt;/a&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;/etc/php5/fpm/php.ini
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Change this line:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;cgi.fix_pathinfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;cgi.fix_pathinfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The other change is to make PHP-FPM listen on a UNIX socket rather than a TCP socket.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;/etc/php5/fpm/pool.d/www.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Change the line:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:9000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/run/php5-fpm.sock&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, restart PHP.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;/etc/init.d/php5-fpm&lt;span class="w"&gt; &lt;/span&gt;restart
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Nginx&lt;/h3&gt;
&lt;p&gt;Now that PHP is configured, you'll want to configure Nginx. There's a very good &lt;a href="https://blog.martinfjordvald.com/nginx-primer/"&gt;primer&lt;/a&gt; by Martin Fjordvald on the basics of Nginx configuration which you can read to get an understanding of what's going on. If you want to dig deeper for various other settings, the &lt;a href="https://nginx.org/en/docs/"&gt;documentation&lt;/a&gt; for Nginx is quite thorough.&lt;/p&gt;
&lt;p&gt;This tutorial is going to have you build Nginx from source, since the .deb packages are not always up to date. It's really not that much harder than setting it up from a package install anyway.&lt;/p&gt;
&lt;p&gt;First, install the packages required to compile the source.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;gcc&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;libpcre3-dev&lt;span class="w"&gt; &lt;/span&gt;openssl&lt;span class="w"&gt; &lt;/span&gt;libssl-dev
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I also prefer to have Nginx use a dedicated system account with no login or password access for a bit of extra security.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;adduser&lt;span class="w"&gt; &lt;/span&gt;--system&lt;span class="w"&gt; &lt;/span&gt;--no-create-home&lt;span class="w"&gt; &lt;/span&gt;--disabled-login&lt;span class="w"&gt; &lt;/span&gt;--disabled-password&lt;span class="w"&gt; &lt;/span&gt;--group&lt;span class="w"&gt; &lt;/span&gt;nginx
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then download and unpack the latest Nginx version.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;https://nginx.org/download/nginx-1.5.6.tar.gz

&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;tar&lt;span class="w"&gt; &lt;/span&gt;-xzvf&lt;span class="w"&gt; &lt;/span&gt;nginx-1.5.6.tar.gz

&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nginx-1.5.6
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The configure command sets the parameters for the build. This is where you can change the default install directory and the different modules that Nginx uses. Nginx doesn't allow you to change modules without rebuilding, so you'll need to select or deselect any modules here. The only module I'll add is the http_ssl module, which will allow you to add SSL to your site later if you wish. I also prefer to just use the default install directory, so I won't change that, but I'll set the user and group Nginx uses to the one I created earlier.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;./configure&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;span class="w"&gt; &lt;/span&gt;--group&lt;span class="o"&gt;=&lt;/span&gt;nginx&lt;span class="w"&gt; &lt;/span&gt;--with-http_ssl_module
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we can build and install Nginx.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;install
&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Nginx Configuration&lt;/h4&gt;
&lt;p&gt;Change to the directory you installed Nginx to:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/local/nginx
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are various methods people use for controlling the sites on their server. The .deb install uses a &lt;code&gt;sites-enabled&lt;/code&gt; and &lt;code&gt;sites-disabled&lt;/code&gt; style configuration, but since I don't have many sites on my server, I prefer to keep each site configuration file in the conf/ folder, and include each one manually in nginx.conf.&lt;/p&gt;
&lt;p&gt;So, for this tutorial, we'll create a ttrss.conf file.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;conf/ttrss.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;My ttrss.conf looks something like this (except I have SSL enabled):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# Tiny Tiny RSS Configuration&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;domainname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;www.domainname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/www/ttrss&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;error_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/ttrss.error.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;access_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/ttrss.access.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;try_files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$uri/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;\.php$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;fastcgi.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# don't use fastcgi_params&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_pass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;unix:/var/run/php5-fpm.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;fastcgi_index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;index.php&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A brief primer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;listen&lt;/em&gt;: the port that the server listens for incoming connections on.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;server_name&lt;/em&gt;: the FQDN (fully qualified domain name) that the server uses for this connection. I set this to listen on both example.com and www.example.com.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;root&lt;/em&gt;: the root directory that the site's files are located at.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;index&lt;/em&gt;: the index file that the server directs traffic to. In this case you only need index.php, but can also include index.html or .htm, or any other file you want to use as a homepage.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;error_log&lt;/em&gt;: the location of the error log for this site.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;access_log&lt;/em&gt;: the location of the access log for this site.
The first location block accepts all incoming requests:&lt;/li&gt;
&lt;li&gt;&lt;em&gt;try_files&lt;/em&gt;: this just makes the URL search engine friendly. Not really necessary in this case, but it doesn't hurt.
The second location block catches all incoming php requests:&lt;/li&gt;
&lt;li&gt;&lt;em&gt;include fastcgi.conf&lt;/em&gt;: this file comes with Nginx and includes all the parameters for using fastcgi. It's almost the same as fastcgi_params, but you'll have issues using fastcgi_params in Ubuntu 12.04, unless you include the line &lt;code&gt;SCRIPT_FILENAME $document_root$fastcgi_script_name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;fastcgi_pass&lt;/em&gt;: the socket that fastcgi passes requests through.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;fastcgi_index&lt;/em&gt;: the index file that fastcgi uses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, you'll need to edit nginx.conf.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;conf/nginx.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The only change that you really need to make to this file is to add the line &lt;code&gt;include ttrss.conf&lt;/code&gt; in the http block, but this is my recommended configuration below.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# Nginx Configuration&lt;/span&gt;

&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;worker_processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# optimal value is number of cpu cores&lt;/span&gt;

&lt;span class="k"&gt;error_log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/error.log&lt;/span&gt;

&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;worker_connections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;http&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Virtual Host Configuration&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ttrss.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Basic Settings&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mime.types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;default_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;application/octet-stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;sendfile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;tcp_nopush&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;tcp_nodelay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;client_header_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;client_body_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;send_timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;20s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Disable Nginx version number in error pages and Server header&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server_tokens&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Silently block all undefined vhost access&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;server_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Gzip Settings&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_disable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"msie6"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_comp_level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_min_length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_vary&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_proxied&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;gzip_types&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, start Nginx.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;/usr/local/nginx/sbin/nginx
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you need to make any changes to Nginx after it's been started, just open and change the config files. Then run this command to reload the Nginx with the new configuration.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;/usr/local/nginx/sbin/nginx&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;reload
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Postgres&lt;/h3&gt;
&lt;p&gt;Tiny Tiny RSS recommends using &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; over MySQL for the database, as PostgreSQL is slightly faster. For a single user, it probably wouldn't make much difference, depending on how many feeds you have. The instructions for installing PostgreSQL are mostly taken from the Ubuntu community wiki &lt;a href="https://help.ubuntu.com/community/PostgreSQL"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Install PostgreSQL.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;postgresql
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Log in to the postgres command line as user postgres.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;postgres&lt;span class="w"&gt; &lt;/span&gt;psql&lt;span class="w"&gt; &lt;/span&gt;postgres
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Change the password for the postgres user. Type in the command below, hit enter, then enter as password. Make sure to save all your passwords in a good password manager somewhere. I recommend &lt;a href="https://keepass.info/"&gt;KeePass&lt;/a&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;assword&lt;span class="w"&gt; &lt;/span&gt;postgres
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While you're still in the postgres command line, create a database and database user for tt-rss. The password must be entered surrounded by single quotes.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# CREATE USER ttrss WITH PASSWORD 'password';&lt;/span&gt;

&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# CREATE DATABASE ttrssdb;&lt;/span&gt;

&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# GRANT ALL PRIVILEGES ON DATABASE ttrssdb to ttrss;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Exit the postgres command line.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c1"&gt;# \q&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From this point, you might be able to get tt-rss to access the database, but I wasn't until I edited a line in the postgresql config to allow access.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;/etc/postgresql/9.1/main/pg_hba.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Add this line to allow tt-rss to use the database:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;local all ttrss md5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now restart PostgreSQL.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;service&lt;span class="w"&gt; &lt;/span&gt;postgresql&lt;span class="w"&gt; &lt;/span&gt;restart
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Tiny Tiny RSS&lt;/h3&gt;
&lt;p&gt;Finally, it's now time to install Tiny Tiny RSS itself. Yeah, I know it takes a while to get here. I assure you, it's worth it in the end, and you shouldn't have to worry about it much at all once you've got it properly set up. The installation instructions for tt-rss can be be found &lt;a href="https://tt-rss.org/redmine/projects/tt-rss/wiki/InstallationNotes"&gt;here&lt;/a&gt;, but once again they seem somewhat incomplete.&lt;/p&gt;
&lt;p&gt;First, make a directory for tt-rss to be served from. This should be the same as the directory you specified as root in your ttrss.conf file for Nginx.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;/var/www/ttrss
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You'll need to set the owner of the directory to the user that you're installing and running tt-rss as.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;chown&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;user:group&lt;span class="w"&gt; &lt;/span&gt;/var/www/
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now change to the directory above.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/var/www
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Download and extract the latest version of Tiny Tiny RSS.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;https://github.com/gothfox/Tiny-Tiny-RSS/archive/1.10.tar.gz

&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;tar&lt;span class="w"&gt; &lt;/span&gt;-xzvf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.10.tar.gz
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Rename the extracted directory so that it matches the root directory you specified earlier, then open the directory.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;Tiny-Tiny-RSS-1.10/&lt;span class="w"&gt; &lt;/span&gt;ttrss

&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/var/www/ttrss
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following folders need to have their permissions changed to be writable by anyone with an account on the system, or tt-rss won't be able to save files there.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;777&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cache/images/&lt;span class="w"&gt; &lt;/span&gt;cache/js/&lt;span class="w"&gt; &lt;/span&gt;cache/export/&lt;span class="w"&gt; &lt;/span&gt;cache/upload/&lt;span class="w"&gt; &lt;/span&gt;feed-icons/&lt;span class="w"&gt; &lt;/span&gt;lock/
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you should be able to navigate in your browser to the site that you are hosting tt-rss from. This should be the same as the server_name you specified in ttrss.conf. If you installed tt-rss into a sub-folder of the domain, then the address will be &lt;code&gt;https://domainname/ttrss/&lt;/code&gt;. If you got the configuration correct, you should see the Tiny Tiny RSS install page.&lt;/p&gt;
&lt;p&gt;The installation page will have a few fields to enter. These will be the credentials for tt-rss to use the database, as well as the full URL that you'll access tt-rss from. Once you've entered the database details, click the 'Test Configuration' button. If there are errors, you'll get a message saying so, and it shouldn't be too hard to figure out what to do from there. If it's good to go, you'll see a text box with a lot of configuration lines. Copy that config data to your clipboard, and then into a config file on your server with:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;nano&lt;span class="w"&gt; &lt;/span&gt;/var/www/ttrss/config.php
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Save that file, and reload tt-rss in your browser. You should now be able to login with the default user &lt;code&gt;admin&lt;/code&gt; and password &lt;code&gt;password&lt;/code&gt;. Once you're logged in, change the admin settings in the preferences at top right.&lt;/p&gt;
&lt;p&gt;The final required step is to set up automatic updating of your feeds. You can skip this, but you'll have to manually click on each feed to check for updates if you don't. The &lt;a href="https://www.gnu.org/software/screen/"&gt;screen&lt;/a&gt; command will permanently run feed updates in the background, defaulting to once every 30 minutes.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;screen&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;php&lt;span class="w"&gt; &lt;/span&gt;./update_daemon2.php
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;You should now have a working installation of Tiny Tiny RSS on your server, accessible from anywhere in the world. If you've used RSS Readers before, you can import your feeds from an OPML file, otherwise, find some good blogs and start adding feeds.&lt;/p&gt;</description><category>hosting</category><category>IT</category><category>Nginx</category><category>RSS</category><category>servers</category><category>tutorial</category><category>Web</category><guid>https://davidbeath.com/posts/installing-tiny-tiny-rss-from-scratch/</guid><pubDate>Wed, 02 Oct 2013 03:43:39 GMT</pubDate></item><item><title>A New Blog</title><link>https://davidbeath.com/posts/a-new-blog/</link><dc:creator>David Beath</dc:creator><description>&lt;p&gt;So, I guess it's time I started to write a blog. I've always read that it's recommended in IT to write a blog, or maybe in any industry these days, in order to have some sort of recognisable professional presence. Or, at the very least, to keep your rants off Facebook.&lt;/p&gt;
&lt;p&gt;At any rate, there are plenty of things I could talk about, and I will. I tend mostly to have strong opinions on Politics, Information Technology, Economics, the Environment, and any intersection between the bunch, though not necessarily in that order. I think I'll start off properly with a politics post next.&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;Anyway, I figure I might as well write about the tools I used to set this blog up. Starting from the bottom of the stack, my server is a VPS hosted by &lt;a href="https://www.linode.com/"&gt;Linode&lt;/a&gt;. I like that I have full control over my machine, without having to worry about the hardware. Even the lowest tier plan gets me more than enough machine for my needs, and the documentation and tools they have are really good. Definitely recommended.&lt;/p&gt;
&lt;p&gt;The server OS is &lt;a href="https://debian.org"&gt;Debian&lt;/a&gt;, because for me it was either that or Ubuntu Server for the easy and familiar option. Fanboys can feel free to flame away at whatever choice is made, but I like something stable.&lt;/p&gt;
&lt;p&gt;For the HTTP server itself, I'm using &lt;a href="https://nginx.org"&gt;nginx&lt;/a&gt;. Apache is just to mainstream, and from everything I've read it doesn't scale as well. Not that scaling should be a problem for me for a long time, if ever, but you never know. I've found nginx to be just as easy, if not easier, to understand and configure compared to Apache anyway.&lt;/p&gt;
&lt;p&gt;Finally, I use &lt;a href="https://getnikola.com/"&gt;Nikola&lt;/a&gt; to generate this blog. Nikola is a static blog generator, so all the files on this site are just plain HTML, no CMS needed. The site design is basically just an unmodified &lt;a href="https://get.foundation/"&gt;Foundation&lt;/a&gt; theme, which for now looks good enough. Besides, if you're not using an RSS reader to read this blog (once you've first visited and decided to keep reading of course), then you damned well should be. Why on earth would you manually visit blogs to read?&lt;/p&gt;
&lt;p&gt;On the non-essential side of things, analytics on the blog are handled by &lt;a href="https://piwik.org"&gt;Piwik&lt;/a&gt;, so that I don't have to send all my data to Google Analytics. The thing I use this server for the most though, is &lt;a href="https://tt-rss.org"&gt;Tiny Tiny RSS&lt;/a&gt;. I find that using an RSS reader is essential for keeping up with the world. Like most everyone else, I used to use Google Reader, but of course anyone who hasn't been living under a rock this year knows the story of how they shut it down, and the gnashing and wailing of teeth that ensued. I contributed my part of that, on my tiny corner of Google Plus and Facebook.&lt;/p&gt;
&lt;p&gt;Just like many others, I decided that if I couldn't trust even Google with my stuff, then it might be better to go self-hosted. Tiny Tiny RSS was the self hosted solution with the most recommendations, and I've been pretty happy with it so far. It's nice to know that you've got a service that no-one is going to arbitrarily remove, just so long as you have a good backup policy in place.&lt;/p&gt;
&lt;p&gt;Someday soon, I might get round to routing my mail through my server as well, though I might like to have it on a different one. A single point of failure for everything I rely on makes me nervous.&lt;/p&gt;
&lt;p&gt;In conclusion, Welcome to my Blog, and don't be afraid to look into self hosting if you're at all technically inclined. It's the 21st century, and all the information you need is out there.&lt;/p&gt;</description><category>hosting</category><category>IT</category><category>RSS</category><category>servers</category><guid>https://davidbeath.com/posts/a-new-blog/</guid><pubDate>Fri, 23 Aug 2013 09:23:54 GMT</pubDate></item></channel></rss>