Shiny on AWS - Create a nice domain name

This article belongs to the series How to deploy a Shiny app on AWS, divided into 7 parts. To access the other articles, use the following table of contents:

In Part 4 of the series, we deployed the Shiny app on the AWS server that we had created.

At the end of the article, we could just type 3.121.42.9:3838 in the browser and our app appeared magically!

Shiny AWS Movie Explorer Final

Yay!

Just as a reminder from the previous article, here is what you have on the server:

  • You deploy the app in the /srv/shiny-server directory.
  • You read the logs of Shiny in /var/log/shiny-server. This helps to understand why your app crashes.
  • You can change the configuration of Shiny in /etc/shiny-server/shiny-server.conf.

These are the three directories you need to remember.

After a while, you get used to it.

Until then, don’t hesitate to reach out to the previous articles.

Now..

I just said we can reach our Shiny app just by typing 3.121.42.9:3838, and.. that’s kind of great!

But seriously, will you tell your friends to type and remember these numbers?

Or tell your client he has to use these numbers?

Not really..

What would be cool would be to have a really nice-looking URL.

For example, I host all my apps on shiny.charlesbordet.com.

Easy to remember, and convenient for everyone.

You can find our app at this address: https://shiny.charlesbordet.com/movie-explorer/.

How to do that?

Three steps:

  1. Get your domain name
  2. Set up the DNS
  3. Set up a reverse proxy

If you’re not familiar with servers, this might feel complicated.

But stay with us. I’ll guide you through each step with screenshots, as usual.

1. Get your domain name

The first step, if you want to use a domain name, is to get one!

This also means buying one.

Right.

It costs money.

Mine (charlesbordet.com) costs $14.99 per year.

But you can find cheaper ones, sometimes for less than 2$ per year.

I got mine at Hover.com, a company specialized in domain names.

I’ve been using them for years and never had any issues.

I’m also using OVH for .fr domains since Hover doesn’t do them.

I will use Hover in the rest tutorial but don’t worry. Pretty much all domain providers have similar interfaces.

Alright!

So let’s say you have bought your cool new domain name!

Now, you must make the link between:

  1. The domain name
  2. The IP address of your server

What do we use for that?

DNS of course!

2. Set up the DNS

DNS stands for Domain Name System.

It is one of the most fundamental services used all over the internet.

Even though pretty much nobody knows what it is.

It’s what allows you to type https://duckduckgo.com in your address bar rather than 23.21.193.169.

In a few words, it makes using the internet way friendlier!

And that’s exactly what we want to do!

We want people to type http://mysupercoolshinyapp.com rather than 3.121.42.9:3838.

Your domain name provider will have a page where you can set up the DNS.

In Hover, simply click on the DNS tab:

DNS on Hover

You can see some default entries here that might be different than my screenshot.

If you’re curious to understand what’s going on in this table, check out the blue box. Otherwise, you can jump right after to continue the tutorial.

Blue Box: A crash course in DNS entries


Each DNS entry indicates where to redirect users when they type your domain name.

Why not have only one entry?

Because you could have charlesbordet.com on one server, then shiny.charlesbordet.com on a different server, and so on. For each specific use, you must add a new row.

The TYPE column can be A to redirect the domain name towards the IP address of a server. It can be CNAME if you redirect the domain name towards another domain name. It can be MX for a mail server.

The HOST column is for the subdomain. The subdomain is everything before your domain. For example, when I type shiny.charlesbordet.com, this is a subdomain of charlesbordet.com. The star * means all subdomains. The @ means the main domain (charlesbordet.com in this case).

The VALUE column depends on the TYPE you chose. If you choose TYPE A, then you must enter an IP address.

The rest is unimportant for us today.

The default values here tell us that the main domain charlesbordet.com and all subdomains *.charlesbordet.com are redirected to the IP address 64.98.145.30.

That is not exactly what we want.

What I would like is to have the subdomain shiny.charlesbordet.com redirecting directly to the IP address of my AWS server.

To do so, remove both rows with TYPE A, and add this one instead:

Create DNS Record on Hover

If you don’t want to use a subdomain and you want your main domain to redirect to your AWS server, then write @ instead of shiny for the hostname.

Finally, my table looks like that:

New DNS with Hover

Now, every time someone types shiny.charlesbordet.com in his browser, he gets redirected automatically to my AWS server!

We’re not done though!

If you try by yourself, you’ll notice it doesn’t work.

Why?

We haven’t specified a port!

You still need to write shiny.charlesbordet.com:3838 to access the app.

Meh..

That’s kind of annoying.

But we’re getting close!

There are two ways to solve this issue:

  1. The quick & dirty way
  2. The proper good long-term solution

The Quick & Dirty port removal solution

If you want something quick that works right now, do the following:

  1. SSH into your AWS server (check part 3 if you’ve forgotten how to do this)
  2. Open your Shiny config file: sudo nano /etc/shiny-server/shiny-server.conf.
  3. Change the row listen 3838 for listen 80.
  4. Restart shiny server by typing sudo systemctl restart shiny-server.

And that’s it!

Now Shiny Server listens on port 80 instead of 3838.

Why 80?

80 is the default HTTP port.

In fact, when you type shiny.charlesbordet.com in your browser, the browser uses port 80 by default.

Before, we had to specify 3838 because it’s uncommon and it can’t guess it.

So, why is it a quick & dirty solution?

Quick, ok.

Dirty, because if tomorrow you want to install another service on your server, such as an RStudio Server, or a Jupyter Notebook server, or a website, you will face the same issue.

And only one service can listen to port 80 at a time.

If you have a Shiny Server and an RStudio Server on the same machine, they must use two different ports.

They can’t both use port 80.

But you still want to have two clean URL such as shiny.charlesbordet.com and rstudio.charlesbordet.com.

So, what to do?

The solution is to use a Reverse Proxy Server like Nginx.

3. Set up a reverse proxy with Nginx

I could tell you exactly what to type in the terminal and be done with it.

But that’s now how I teach.

I prefer to have you understand what you’re typing.

If tomorrow you want to do something slightly different, you’ll be able to do it.

So, let’s start with..

What the hell is a reverse proxy?

Think of your server like a house that has many doors.

65,535 doors exactly.

And let’s call these doors ports, okay? porte is the French word for door.

If you want to reach out for some information in the house, you must pass one of these ports, ask the guy behind, and then get back home with the information.

Well, Shiny Server is one of these information providers.

It’s located by default at port 3838.

And let’s say you also have a service at port 8080.

That’s the default port if you install RStudio Server.

If you knock at port 3322, nobody will reply, because nobody’s there.

Without Reverse Proxy

This works.

But it’s not handy because you have to knock at the right door.

As we said before, you have to specify the port number in the URL, such as shiny.charlesbordet.com:3838 and it’s ugly.

What if, instead, there was a doorman at the main entrance that could bring you to the right person?

You ring at the main entrance and ask for Shiny Server, and you get to it right away.

And if you want RStudio Server, you ring at the main entrance and ask for RStudio Server.

Nestor

Wayy easier!

No messing around trying to find the right door.

This doorman is called a reserve proxy.

Nginx is the best reverse proxy server out there.

With Reverse Proxy

Instead of typing the port number, you can only type shiny.charlesbordet.com and talk to Nginx.

Nginx understands you need to access the Shiny Server, so it fetches the right information and get it back to you directly.

To do so, we need to:

  • Install Nginx on your server.
  • Configure Nginx.

Install Nginx

This is the easiest step.

After SSH-ing to your AWS instance (check part 3 and stop forgetting how to do it), type the following:

$ sudo apt install nginx

And Nginx is installed.

Easy.

Configure Nginx

Now for the tricky part.

First, change directory (cd) to where Nginx is installed:

$ cd /etc/nginx
$ ls
auth          fastcgi_params  mime.types         proxy_params     snippets
conf.d        includes        modules-available  scgi_params      uwsgi_params
dhparam.pem   koi-utf         modules-enabled    sites-available  win-utf
fastcgi.conf  koi-win         nginx.conf         sites-enabled

The ls command list all the files in this directory.

What’s of interest for us is the nginx.conf file, but we won’t touch it.

Instead, well jump to the sites-available folder and create a new file specifically for Shiny Server.

$ cd sites-available
$ sudo nano shiny.conf

And that’s where we write the config file:

server {
    # listen 80 means the Nginx server listens on the 80 port.
    listen 80;
    listen [::]:80;
    # Replace it with your (sub)domain name.
    server_name shiny.charlesbordet.com;
    # The reverse proxy, keep this unchanged:
    location / {
        proxy_pass http://localhost:3838;
        proxy_redirect http://localhost:3838/ $scheme://$host/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 20d;
        proxy_buffering off;
    }
}

There isn’t much going on here but it can look intimidating.

listen

The beginning states that the Nginx server now listens on port 80. Exactly what we wanted to do with our Shiny Server.

But since only ONE service can listen on port 80, we give it to Nginx.

In short, we’re telling our doorman to wait at the main entrance.

server_name

The server_name is what the user types to access the app.

In my case, I want the user to access my Shiny app on the subdomain shiny.charlesbordet.com.

Replace the value with your own domain name.

location

Finally, everything inside location is the reverse proxy happening.

We’re giving instructions to our doorman:

If the user comes and asks for shiny.charlesbordet.com, then guide him through the house at door 3838.

And that’s it!

If you want to use this config file for RStudio Server, you can add a second file called rstudio.conf, and inside you put the same config and only replace two things:

  1. The server_name
  2. The port number

There is one thing left to do.

Save the file and go back to the terminal.

We need to create a shortcut inside the sites-enabled directory:

$ cd ../sites-enabled
$ sudo ln -s ../sites-available/shiny.conf .

Why is that necessary?

The deal is that Nginx does NOT look at the sites-available folder.

Only at the sites-enabled folder.

So we create the conf file inside sites-available and then we create a shortcut inside sites-enabled.

Why? So that if tomorrow you want to temporarily deactivate your access to Shiny, you only have to delete the shortcut.

You don’t have to delete the entire conf file and regret it later.

Now that our reverse proxy is set up, we only need to restart Nginx to take into account the changes.

First:

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

This ensures that the conf file is correct.

And:

$ sudo systemctl restart nginx

Congrats!

Your Shiny app is now accessible on a good-looking URL such as https://shiny.charlesbordet.com/movie-explorer/!

The last part was not easy, but that’s the best way to do it.

Plus, it comes with other benefits.

Such as..

Making your app secure with HTTPS!

That’s what you’ll learn in the next article.

Stay tuned!

You like my articles?

To get updated when I publish new articles, subscribe here:

Updated:

Comments

Sono

This guide is excellent! What would you need to do if you wanted separate custom domains for different shiny apps hosted in my directory? Would I just use the same procedure that you describe for doing an rstudio server and shiny?

Charles

Hi Sono, I’m glad you like it :)

To create separate custom domains with the same Shiny Server:

Hm I’m not sure actually. My first approach would be to set up a redirection, for example from shiny.example.com/myapp2 to myapp2.com. I will show how to set up a redirection with Nginx in the next article (yet to be written!)

It’s different than having an RStudio Server and Shiny Server side by side, because in this case you can have different ports. Say 8080 for RStudio and 3838 for Shiny. Then you set up Nginx accordingly.

Rich Pauloo

I’ve spent this Sunday following your guide from parts 1-5, and it’s the best guide so far on the topic! Thank you for writing it. I look forward to reading your next two posts on HTTPS and authentication. Do you think you’ll use shiny-auth0?

Charles

Hey Rich! Thanks for the good words :) For the authentication part, I’ll probably use auth0 indeed because that seems to be the best solution at the moment, but I know some people are using others, so I might investigate a little bit over other existing solutions to pick the best one!

Leave a Comment

Required fields are marked *

Loading...

Comments are validated manually. The page will refresh after validation.