Deploying the Application to a Virtual Machine
Finding Domain Name
We can find out the default hostname of our virtual machine using the host
command on the public IP address.
host $FLOATING_IP
15.253.214.128.in-addr.arpa domain name pointer vm3814.kaj.pouta.csc.fi.
We can also configure our own domain name by pointing DNS records to the virtual machine IP address. You read more about DNS services in cPouta in the docs.
Connecting to the Virtual Machine
Now, we can connect to our virtual machine using SSH with our SSH key.
ssh ubuntu@$FLOATING_IP -i ~/.ssh/$KEY_NAME.pem
Attaching the Persistent Volume
Let's begin by creating a file system on the persistent volume.
sudo mkfs.xfs /dev/vdb
Now can mount the persistent volume. Let's define a variable for the mount location, then create a directory to the mount location and finally mount the persistent volume to the mount location.
VOLUME=/media/volume
sudo mkdir -p $VOLUME
sudo mount /dev/vdb $VOLUME
We also need to change the ownership of the volume to the cloud user for reading and writing data.
sudo chown $USER:$USER $VOLUME
Installing the Julia Language
Once we have connected to the virtual machine via SSH, we need to install Julia language and our Genie web application using the command line. So let's begin by installing the Julia language.
# Set URL for downloading Julia binaries
JULIA_URL="https://julialang-s3.julialang.org/bin/linux/x64/1.6/julia-1.6.2-linux-x86_64.tar.gz"
# Set name for the downloaded archive
JULIA_ARCHIVE="$HOME/julia.tar.gz"
# Download the Julia language binaries
curl -o $JULIA_ARCHIVE $JULIA_URL
# Uncompress (-z) and extract (-z) files (-f) from archive
tar -x -z -f $JULIA_ARCHIVE
# Remove the archive file after extraction
rm $JULIA_ARCHIVE
# Add symbolic link of Julia executable to /usr/bin so its found on the PATH
sudo ln -s "$HOME/julia-1.6.2/bin/julia" "/usr/bin/julia"
Installing the Genie Application
Next, we can install our Genie web application from GitHub.
GH_USER="csc-training"
GH_REPO="GenieWebApp.jl"
# Define application directory
export GENIE_APP="$HOME/$GH_REPO"
# Clone the Genie application from the GitHub repository to HOME directory
git clone "https://github.com/$GH_USER/$GH_REPO.git" $GENIE_APP
# Change directory to GenieWebApp.jl
cd $GENIE_APP
# Install GenieWebApp.jl as Julia package
julia -e "using Pkg; Pkg.activate(\".\"); Pkg.instantiate(); Pkg.precompile(); "
# Setup Genie environment variables
export GENIE_ENV="prod"
export EARLYBIND="true"
# Give execution privileges to `bin/server` script
chmod +x ./bin/server
We should also link the data
and log
directories inside the Genie application to the persistent volume with symbolic links.
sudo mkdir -p $VOLUME/data
sudo ln -s $VOLUME/data $GENIE_APP/data
sudo mkdir -p $VOLUME/log
sudo ln -s $VOLUME/log $GENIE_APP/log
Running the Genie Application
Next, we need to create a new Linux Screen for running the web server as a background process.
screen -S genie
Then, let's change our working directory to the Genie application directory.
cd $GENIE_APP
We will use a reverse proxy (Nginx) to serve static files and route dynamic content to Genie server. For this reason, modify configuration settings in the production environment in config/env/prod.jl
such that the Genie server does not handle static files.
const config = Settings(
server_port = 8000,
server_host = "0.0.0.0",
log_level = Logging.Error,
log_to_file = true,
# set to false when using reverse proxy
server_handle_static_files = false
)
On the new screen, let's execute the./bin/server
script to start a server.
./bin/server
We can exit the screen by holding Ctrl
and pressing a
and then d
key. We can retach the screen again by using the screen -r genie
command if we need to.
Installing and Configuring Nginx Server
We can install Nginx on Ubuntu using the Advanced Package Tool (APT).
sudo apt-get update --yes
sudo apt-get install nginx --yes
sudo systemctl start nginx
sudo systemctl enable nginx
Next, we need to configure Nginx for our Genie application by creating a configuration file to the available sites directory. We can create the file using the nano
editor.
sudo nano /etc/nginx/sites-available/genie
On the Nano editor, add the following Nginx configurations:
server {
listen 80;
listen [::]:80;
# Replace `<domain-name>` your domain name, e.g., `example.com`.
# You can find hostname using command `host <public-ip>`.
server_name <domain-name>;
root /home/ubuntu/GenieWebApp.jl/public;
index welcome.html;
# Serve static content via Nginx
location ~ ^/(css|img|js)/genie {
root /home/ubuntu/GenieWebApp.jl/public;
}
location ~ ^(error-*.html|favicon.ico|robots.txt) {
root /home/ubuntu/GenieWebApp.jl/public;
}
# Serve dynamic content via Genie
location / {
proxy_pass http://localhost:8000/;
}
}
Next, we enable the configuration by creating a symbolic link for the configuration file to enable the sites directory.
sudo ln -s /etc/nginx/sites-available/genie /etc/nginx/sites-enabled/genie
We should also remove the default site from enabled sites.
sudo rm -f /etc/nginx/sites-enabled/default
Now, we can restart Nginx to make the configuration effective.
sudo systemctl restart nginx
The web application should be available via HTTP.
Enabling HTTPS with Certbot
We can set up HTTPS for Nginx on Ubuntu 20.04 using Certbot. Before installing Certbot, we need to ensure that we have the latest version of the Snap package manager which comes preinstalled on Ubuntu 20.04.
sudo snap install core; sudo snap refresh core
We can install Certbot via Snap in classic mode.
sudo snap install --classic certbot
Next, we make certbot
command available in the command line by creating a symbolic link of the certbot
executable to /usr/bin
.
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Now, we can use Certbot to retrieve a certificate and edit our Nginx configuration, turning on HTTPS access in a single step.
sudo certbot --nginx
The web application should now be available via HTTPS.