Frontend setup - moulos-lab/edimo GitHub Wiki

VESTA frontend setup

Instructions for setting up the VESTA application frontend for clinical genomics. The system comprises two machines (VMs or physical). The first one hosts the processing backend, and the database and listens to API calls from the front-end. The second one hosts the front-end (appsmith).

Prerequisites

System packages

The following system packages are required on both machines.

sudo apt update
sudo apt upgrade
sudo apt install apt-transport-https software-properties-common dirmngr \
    build-essential zlib1g-dev libdb-dev libcurl4-openssl-dev libssl-dev \
    libxml2-dev libsodium-dev apache2 certbot python3-certbot-apache

Docker

The VESTA frontend runs on appsmith which runs with Docker.

# Add repo
sudo apt-get update
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install
sudo apt-get install docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose docker-compose-plugin

# Test
sudo docker run hello-world

# Add the current user to the docker group so as not to run with sudo each time
sudo usermod -aG docker `whoami`

# Restart your session

appsmith

We install appsmith in the front-end machine. We follow the instructions here assuming that Docker is installed as mentioned above. Note that apache should be stopped for the default configuration:

sudo service apache2 stop

IMPORTANT: The new version of docker-compose does not start as mentioned in appsmith docs but rather:

docker compose up -d

Other services, ports and embedding

In order to run the application in a web address more "independent" of appsmith routing, apache should be configured to listen to the default port and appsmith to another port which will not be visible to the end user. Then the application can be embedded in an iframe. However, many firewalls restrict the access to not well-known ports, therefore, to ensure access, reverse proxying should be enabled, along with a few other modules:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_html
sudo a2enmod headers

sudo systemctl restart apache2

Suppose that we want appsmith to listen to port 8181. Then, the docker-compose.yml should look like:

services:
   appsmith:
     image: index.docker.io/appsmith/appsmith-ee
     container_name: appsmith
     ports:
         - "8181:80"
         - "443:443"
     volumes:
         - ./stacks:/appsmith-stacks
     restart: unless-stopped

Then, stop and restart appsmith:

docker compose down
docker compose up -d

Next, we setup reverse proxying in an apache virtual server, written in e.g. /etc/apache2/sites-available/appsmith.conf:

<VirtualHost *:80>
    ServerName THE_IP_ADDRESS_OR_HOSTNAME

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8181/
    ProxyPassReverse / http://127.0.0.1:8181/

    ErrorLog ${APACHE_LOG_DIR}/appsmith_error.log
    CustomLog ${APACHE_LOG_DIR}/appsmith_access.log combined
</VirtualHost>

followed by

sudo a2ensite appsmith
sudo systemctl restart apache2

Then, the embedding can take place. Edit the file /var/www/html/vesta/index.html:

sudo mkdir -p /var/www/html/vesta
sudo nano /var/www/html/vesta/index.html

and paste the following:

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>FGF-LIMS</title>
</head>
<body>
  <iframe id="embeddedAppsmith" src="APPSMITH_EMBED_ADDRESS" 
  scrolling="yes" seamless="seamless" frameBorder="0" style="display:block; width:100%; height:100vh;"></iframe>
</body>
</html>

Everything should be in place now and VESTA accessible from the main IP address or host name.

Running under HTTPS

In order to have SSL (the easiest way is to use Let's Encrypt), additional Apache modules must be enabled and certain modifications must be done in the config files. Note that in our case, the SSL funtionality of appsmith will not work as we don't want all the appsmith studio exposed under the domain name. Also, the default 443 port in appsmith must be reconfigured (e.g. 8443).

Additional modules:

sudo a2enmod ssl

sudo systemctl restart apache2

The docker-compose.yml (change port 443):

services:
   appsmith:
     image: index.docker.io/appsmith/appsmith-ee
     container_name: appsmith
     ports:
         - "8181:80"
         - "8443:443"
     volumes:
         - ./stacks:/appsmith-stacks
     restart: unless-stopped

Next, we setup reverse proxying in an apache virtual server, written in e.g. /etc/apache2/sites-available/vestatmp.conf:

<VirtualHost *:80>
    ServerName vesta.edimo.gr
    ProxyPass "/vesta" "!"
    Alias "/vesta" "/var/www/vesta"

    <Directory "/var/www/vesta">
        Require all granted
    </Directory>

    ProxyPreserveHost On
    ProxyPass "/" "http://127.0.0.1:8181/"
    ProxyPassReverse "/" "http://127.0.0.1:8181/"
</VirtualHost>

This serves as the basis where certbot will operate. Then, restart Apache:

sudo systemctl reload apache2

We are now ready to create and deploy the Let's Encrypt certificate:

sudo certbot --apache -d vesta.edimo.gr

certbot makes changes in the vhost file above and creates a new one which are not suitable for our setup. We deactivate them:

sudo a2dissite vestatmp
sudo a2dissite vestatmp-le-ssl.conf

and create the following /etc/apache2/sites-available/vesta.conf. Note the proxying to appsmith paths (api, libraries, etc.) which are crucial for the custom application embedding.

# Redirect all HTTP traffic to HTTPS
<VirtualHost *:80>
    ServerName vesta.edimo.gr
    RewriteEngine On
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName vesta.edimo.gr

    # SSL configuration
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/vesta.edimo.gr/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/vesta.edimo.gr/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    # 1. Serve static landing page
    DocumentRoot /var/www/html/vesta
    <Directory "/var/www/html/vesta">
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # 2. Proxy Appsmith paths (on 8443)
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
    
    # Allow self-signed internal SSL connection
    SSLProxyEngine On
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off

    # Proxy rules
    ProxyPass        "/app/" "https://127.0.0.1:8443/app/"
    ProxyPassReverse "/app/" "https://127.0.0.1:8443/app/"

    ProxyPass        "/api/" "https://127.0.0.1:8443/api/"
    ProxyPassReverse "/api/" "https://127.0.0.1:8443/api/"

    ProxyPass        "/static/" "https://127.0.0.1:8443/static/"
    ProxyPassReverse "/static/" "https://127.0.0.1:8443/static/"

    ProxyPass        "/pageService.js" "https://127.0.0.1:8443/pageService.js"
    ProxyPassReverse "/pageService.js" "https://127.0.0.1:8443/pageService.js"

    ProxyPass        "/assets/" "https://127.0.0.1:8443/assets/"
    ProxyPassReverse "/assets/" "https://127.0.0.1:8443/assets/"

    ProxyPass        "/src/" "https://127.0.0.1:8443/src/"
    ProxyPassReverse "/src/" "https://127.0.0.1:8443/src/"

    ProxyPass        "/libraries/" "https://127.0.0.1:8443/libraries/"
    ProxyPassReverse "/libraries/" "https://127.0.0.1:8443/libraries/"

    # WebSocket proxy (required for live editing & embeds)
    ProxyPass "/ws/" "wss://127.0.0.1:8443/ws/"
    ProxyPassReverse "/ws/" "wss://127.0.0.1:8443/ws/"

    # Optional: you can still expose studio on its own port if needed
    # ProxyPass "/studio/" "http://127.0.0.1:8443/"
    # ProxyPassReverse "/studio/" "http://127.0.0.1:8443/"
</VirtualHost>
</IfModule>

followed by

sudo a2ensite vesta
sudo systemctl reload apache2

The file /var/www/html/vesta/index.html should become:

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>VESTA</title>
</head>
<body>
  <iframe id="embeddedAppsmith" src="https://vesta.edimo.gr/app/edimo-app/authentication-688b74e4661f023f1443d782?branch=main&embed=true"
  scrolling="yes" seamless="seamless" frameBorder="0" style="display:block; 
  width:100%; height:100vh;"></iframe>
</body>
</html>
⚠️ **GitHub.com Fallback** ⚠️