Home Serve services through Docker with Nginx
Post
Cancel

Serve services through Docker with Nginx

You’re running most of the services on your server with Docker, so everything is nicely sandboxed and can’t annoy each other. It would, obviously be nice if they were also accessible easily through a domain name. But what should you use? I say Nginx. (Pronounced engine x)

Nginx is according to Wikipedia a

web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.

But for this blog post we’re mostly interested in it’s web server and reverse proxy capabilities. Though we’ll mostly be looking into it’s reverse proxy feature because for this situation, it’s the most interesting.

The first few steps of setting up Nginx are, installing it on the server, and pointing a domain’s DNS to that server. But we won’t be looking into those since they feel a little out of scope for this post. I’ll be linking some things about this at the end of this post.

Alright we have Nginx installed on our server, and the basic set up is done, as well as our domain now pointing to our server. Let’s create a very basic VHost, or Virtual Host, which will tell Nginx how to deal with a request from a specific domain.

1
2
3
4
5
6
7
8
9
server {
    server_name example.duxez.dev;
    listen 80;
    root /var/www/example.duxez.dev;

    location / {
        index index.html
    }
}

In this vhost configuration we are listening for requests coming in on example.duxez.dev on port 80 (http port). That’s what ‘server_name’ and ‘listen’ define.

Next we specify the root directory where we want to look for files to serve. In this case that’s /var/www/example.duxez.dev.

And last we define the block location /. A location block allows us to define specific behavior for a location on our domain, where / is simply the root of the full domain. So in this case example.duxez.dev.

For this block, we tell Nginx that it should be looking for a file named index.html to serve for the initial request.

Serving your service that’s running in Docker

Realistically, we can already access our service now by just going to our domain and adding :PORT_NUMBER but that’s of course not what we want, so let’s slightly change our vhost configuration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
    server_name example.duxez.dev;
    listen 80;

    location / {
        proxy_pass https://localhost:9443;

        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }
}

In the above configuration, we’ve removed the root and index directives and added 5 proxy_ directives.

The first of which is the actual proxy_pass which let’s Nginx redirect our request to the url our service is actually running on (locally). So in the example we set it to https://localhost:9443 which in this case would have to be a Docker service that’s bound to port 9443. Example of a service that by default binds to this port is Portainer.

Next we have 4 proxy_set_header directives, which allows us to redefine or append fields to the request header that is passed to the proxied server (our Docker service).

They are all basic HTTP headers, and we simply set them to Nginx variables so the original values of these headers are passed to our service.

With this basic set up, you should be able to let your domain go to your Docker service, without requiring a port in the URL.

How to set up Nginx
Point your domain to your server

This post is licensed under CC BY 4.0 by the author.