Reverse Proxying to Docker Containers with Nginx
On my personal VPS I host a handful of websites accessed from a variety of domains and sub-domains, as well as a few more involved webapps such as tt-rss. Historically applications that cross multiple programming languages and databases have been a terrible pain to deploy and keep running on a private server, but since containers have arrived this has become a lot easier.
On my server, I wanted to have a web server listening on the standard http/https ports proxying traffic for a variety of sites and applications, based on the domain/sub-domain in the request. Some of these applications would be hosted by containers running on other ports. The following post outlines how to do this with CentOS 7, Nginx, and Docker. I also wanted to be able to connect securely to these so in the examples below, you will see references to my LetsEncrypt certificates being used for various sub-domains.
You will need to install nginx and docker.
This post also assumes you are have DNS for your domain(s) pointing to your server, and optionally have familiarized yourself with LetsEncrypt and generated relevant certificates.
Static Web Content
Several of the sites I host are just static web content, most notably this blog which I recently started writing with Hugo. (an immense relief after years Drupal, php, and databases) For this kind of content we don’t really need Docker, nginx is perfectly capable of hosting these easily.
Your main /etc/nginx/nginx.conf should look something like this:
After this you can drop new config files into /etc/nginx/conf.d/ for each new site/sub-domain you want to host.
My configuration for this blog, including SSL using LetsEncrypt certs looks like this:
Running Web Apps as Containers
For the most part getting your applications running in containers will need to be an exercise for the reader. For tt-rss I simply used the Docker setup from the clue/ttrss image.
You should now have tt-rss running on port 3001, however you do not need to open this port to the world, nginx is just going to proxy to it over localhost.
You can now add nginx config to forward traffic to it based on the domain in the request, in this example
You can now run any open source webapp of your choosing on your VPS, and expose it securely over https without resorting to ports in your URLs. Just get your container running on a local port, and drop a new nginx config in place.