Revel for Production Setup on Ubuntu with Nginx and Supervisor

July 11, 2018 by Stuart Kuentzel

I recently launched a Revel app, and despite their relatively good docs, I really had to piece together how to get this thing running on my Ubuntu 16.04 server. So today, I’m going to go through how to launch a Revel app on Ubuntu, with NGINX and Supervisor. We’ll use the “Hello World” revel app, but feel free to use whatever you’ve been working on. This article assumes you already have a fresh instance of Ubuntu 16.04 on the server that you have SSH access to. Keep in mind, each part of the setup is worthy of it’s own article, this is just a speed-through to get the Revel app working live.

Install Go

Props to teadmin.net for making this a really painless process. After you SSH into your server, run each command one by one.

sudo apt-get update
sudo apt-get -y upgrade
wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
sudo tar -xvf go1.10.3.linux-amd64.tar.gz
sudo mv go /usr/local

Now that it’s downloaded, let’s configure our Go environment on the server. Run the following commands one by one…

The GOPATH can be whatever you want, it’s where all your Go stuff is going to live.

export GOROOT=/usr/local/go
export GOPATH=$HOME/Projects/Go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

This will add the go command to our current session. You can also run nano ~/.profile and paste the above commands inside to permanently add go to your environment.

Once you have saved that, run go version, and we should print something like go version go1.10.3 linux/amd64.

Install Revel

First, let’s get the Revel framework. Run go get github.com/revel/revel in your terminal. Next, let’s get the Revel command tool to package up our app when we’re ready. go get github.com/revel/cmd/revel. Now if you run revel version in your command line, it should tell you which version you’ve installed.

Pull in your app via git

In the terminal, cd into cd ~/Projects/Go/src/github.com. From there, run mkdir <YOUR GITHUB HANDLE> and cd <YOUR GITHUB HANDLE>. Clone your git repo into this directory.

Don’t have an existing revel project? No worries. Inside the newly created folder, run revel new myapp to create a fresh Revel app. Make sure your newly created app is inside the github/your-handle folder (it might get created inside ~/Projects/Go/src. If that’s the case, just run mv ~/Projects/Go/src/myapp ~/Projects/Go/src/github.com/{YOUR_HANDLE}).

Once you’re all setup, run revel run github.com/my-handle/myapp, and it will start listening on port 9000. Cool, it’s working, for now we can stop the revel server.

Install Nginx

In the termainl, run the following commands…

sudo apt-get update
sudo apt-get install nginx

This installs Nginx. Run sudo ufw app list to see the list of available applications. We won’t dig deeply into configuring your filewall, there are plenty of articles on that. Run sudo ufw allow 'Nginx HTTP' and sudo ufw allow 'OpenSSH'. First time I did this, I locked myself out of my server by now allowing SSH. Run sudo ufw enable to enable the firewall, and run sudo ufw status to double check what you set up. You should see OpenSSH, OpenSSH (V6), Nginx HTTP, and Nginx Http (v6) all allowed. Next, run sudo systemctl start nginx to have systemcontrol start that for us.

Route traffic to port 9000

Next, we’ll configure a proxy pass in Nginx to direct traffic to our Revel app. sudo nano /etc/nginx/sites-available/default to edit the default config. Find the location / line and replace it with the following. Remember to put the correct root.

location / {
        root /Projects/Go/src/github.com/YOURGITHUBHANDLE/myapp;
        try_files index.html @app;
}

Below this block, add a new block…

location @app {
        proxy_pass http://localhost:9000;
}

The first block will point to the second and pass traffic to our Revel app. Make sure you don’t have any errors by running sudo nginx -t. Then restart Nginx, sudo systemctl restart nginx.

Build Your Revel App for Prod

First, let’s create a folder for our Revel packages to live. mkdir ~/Packages. In our case, let’s also make a folder for the specific app we’re launching, mkdir ~/Packages/myapp.

Next, we’ll actually package up our app. Run revel build github.com/{YOUR_HANDLE}/myapp ~/Packages/myapp prod. This will build our app for prod and create a run.sh file that we’ll run with Supervisor.

Make sure it built properly by running ls ~/Packages/myapp, you should see a run.sh file, which is what we’ll be using.

Install + Config Supervisor

Getting Supervisor installed is easy enough. Just run sudo apt-get install supervisor followed by sudo service supervisor restart. After that, we’ll have to create a config to launch revel when the server starts. We’ll create a file called myapp.conf by running sudo nano /etc/supervisor/conf.d/myapp.conf. Inside of that file, paste the following…

[program:myapp]
command=bash /home/ubuntu/Packages/myapp/run.sh
autostart=true
autorestart=true
stopasgroup=true
stopsignal=QUIT
user=ubuntu
stdout_logfile=/var/log/supervisor/%(program_name)-stdout.log
stderr_logfile=/var/log/supervisor/%(program_name)-stderr.log

You’ll notice that the path in the command param is an absolute path to our newly created package. You’ll also notice, we’re setting up error logs, so if god forbid anything goes wrong, debugging isn’t a nightmare. Logs can be watched by running tail -f /var/log/supervisor/myappstderr.log.

All that’s left is to make supervisor aware of the changes we’ve made. Run sudo supervisorctl reread, then sudo supervisorctl update. To make sure it worked, you can run sudo supervisorctl. If there are any errors, you can check the logfile.

And that’s it. If you hit your IP, your Revel app should show up! This is a pretty simple overview of the setup and config process, but hope it helps get that first Revel app live and into production.

© 2018