Configuring the app

If you need to run multiple apps from a single domain or subdomain, you can use a reverse proxy to redirect traffic to the appropriate app. For instance, say you want to serve your Genie app at test.com/genieapp. To make this work, you'll need to set the base URL path with the environment variable BASEPATH. This can be done in the REPL with

ENV["BASEPATH"] = "/genieapp"
using GenieFramework; Genie.loadapp(); up();

or in the terminal with

BASEPATH="/genieapp" julia --project -e "using GenieFramework; Genie.loadapp(); up(async=false);"

Genie will automatically append the base path to its own asset paths. If you have any links that point to the app itself, e.g., a file in the public folder or a link to another page, you'll need to add the base path manually. You can do so with the helper Router.link_to, which works like this:

julia> @page("/foo/bar/baz", "nop")
julia> routes()
10-element Vector{Genie.Router.Route}:
 [GET] /foo/bar/baz => #5 | :get_foo_bar_baz
 
julia> Router.to_link(:get_foo_bar_baz)
"/foo/bar/baz"

julia> Genie.config.base_path = "/my/hosting/thing"  # use this to change the base path if Genie is already loaded. Otherwise set the BASEPATH env var before running the app
"/my/hosting/thing"

julia> Router.to_link(:get_foo_bar_baz)
"/my/hosting/thing/foo/bar/baz"

For example, this is how you'd use it in a navigation bar in a page:

Html.div(style="display: flex; gap: 20px;", [
        a(href="$(Router.link_to(:get_eda))",
            "Exploratory data analysis"
        ),
        a(href="$(Router.link_to(:get_ml))",
            "Neural network training"
        ),
        a(href="$(Router.link_to(:get_api))", target="_blank",
            "API"
        )
    ])

Finally, note that if you're developing locally and want to access your app at /, you'll need to remove the BASEPATH variable. Now you can proceed to configure the reverse proxy.

NGINX reverse proxy

When used as a reverse proxy, NGINX will listen requests made on port 80 (HTTP) and redirect traffic to the Genie app running on port 8000 (default Genie setting that can be changed).

To improve the app's performance, NGINX will also be used to serve the app static files. That is, the content under the ./public folder.

Finally, it can as well handle HTTPS requests, which will also be redirected to the Genie app listening on port 8000.

First, install NGINX with:

sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx
sudo systemctl enable nginx

A configuration file then needs to to be created to indicate on which port to listen (80 for HTTP) and to which port to redirect the traffic (8000 for the default Genie config).

Create a config file in /etc/nginx/sites-available with sudo nano my-genie-app. Then, add the following to my-genie-app:

server {
  listen 80;
  listen [::]:80;

  server_name   test.com;
  root          /home/ubuntu/MyGenieApp/public;
  index         welcome.html;

  location /genieapp/ {
      proxy_pass http://localhost:8000/;
      #websocket specific settings
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
  }
}
  • server_name: refers to the web domain to be used. It can be put to an arbitrary name if the app is only to be served directly from the server public IP.
  • root: points to the public subfolder where the genie app was cloned.
  • index: refers to the site index (the landing page).
  • location: indicates the path to be used to access the app. In this case, the app will be served at test.com/genieapp. Note that the trailing slash is needed.

To enable the reverse proxy, add the config file to the sites-enabled with a symlink:

sudo ln -s /etc/nginx/sites-available/my-genie-app /etc/nginx/sites-enabled/my-genie-app

Then restart the server to make changes effective:

sudo systemctl restart nginx

Serving static assets through NGINX

To improve performance, it is recommended that static assets are served by NGINX. To do so, define locationsto indicate static content folders to be served by NGINX.

  location /css/genie {
      proxy_pass http://localhost:8000/;
  }
  location /img/genie {
      proxy_pass http://localhost:8000/;
  }
  location /js/genie {
      proxy_pass http://localhost:8000/;
  }

These locations are needed when the server_handle_static_file is set to false in the Genie app settings.

Enabling HTTPS

To enable HTTPS, a site-certificate will be needed for the domain on which the site will be served. A practical approach is to use the utilities provided by certbot.

Following provided instructions for NGINX on Ubuntu 20.04:

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Then, using the certbot utility, a certificate will be generated and appropriate modification to NGINX config will be made to handle support for HTTPS:

sudo certbot --nginx

Note that this step will check for ownership of the test.com domain mentioned in the NGINX config file. For that validation to succeed, it requires to have the A record for the domain set to 123.123.123.123.