Deploy a basic Vapor app with Nginx and Supervisor

This article takes you through the process of deploying a simple vapor app to a VPS. I am using digital ocean but the hosting provider does not matter as long as you have an instance running Ubuntu 16.04 and you have ssh access to the machine.

Prerequisites:

  1. An Ubuntu 16.04 instance with ssh access. I strongly recommend reading the article here before you proceed.
  2. Familiarity with a terminal text editor like nano, vi or emacs.
  3. Familiarity with basic bash commands.

Install and setup Nginx

Install Nginx by running the following commands:

sudo apt-get update
sudo apt-get install nginx

Add a rule to firewall to allow TCP connections on port 80. (Only needs to be done if firewall is enabled)

sudo ufw allow 'Nginx HTTP'
sudo ufw status

Check if Nginx is running systemctl status nginx

Output of Nginx status command

Finally, you can check if nginx is setup correctly by sending a GET request from your browser to your server’s domain or ip. If you see the welcome page below, you have successfully setup Nginx.

Nginx welcome page

If you do not see this page, check out this detailed tutorial.

Install and setup Vapor

Install Swift and Vapor with the following commands.

eval "$(curl -sL https://apt.vapor.sh)"
sudo apt-get install swift vapor
eval "$(curl -sL check.vapor.sh)"

If this outputs “Compatible with Vapor 2”, you are good to proceed.

Create a basic vapor project.

vapor new hello

Note: If you have an existing vapor project, you can clone that repository from github. But remember to replace “hello” with your projectname in the rest of the tutorial.

Configure Nginx to forward requests to the Vapor App

Change the default configuration file in /etc/nignx/sites-available so that it looks like the following snippet.

server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
try_files $uri @proxy;
location @proxy {
proxy_pass http://127.0.0.1:8080;
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Server;
proxy_connect_timeout 3s;
proxy_read_timeout 10s;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
}
}

Run the server and test if Nginx is forwarding requests to Vapor App.

sudo systemctl restart nginx
cd ~/hello
vapor build
vapor run

Open http://YourDomainOrIP/hello in your browser, it should show the message “hello world”.

It works! We are done, right? No.

Press Ctrl-C or close the terminal window running the server and it stops working. You want the server to run even when you put your system to sleep and go get a coffee and that’s why you need Supervisor. Supervisor runs the server process in background, restarts the process if it is killed by any error and also logs all errors in a file.

Install and setup Supervisor

sudo apt-get update
sudo apt-get install supervisor

Create a new config file /etc/supervisor/conf.d/hello.conf using the following snippet.

Don’t forget to replace “sammy” with your username and also update the project directory path.

[program:hello]
command=vapor run --env=production
directory=/home/sammy/hello/ # Put correct path here
autorestart=true
user=sammy # Put username here
stdout_logfile=/var/log/supervisor/%(program_name)-stdout.log
stderr_logfile=/var/log/supervisor/%(program_name)-stderr.log

Load the configuration file and run “hello” in background using supervisor.

sudo supervisorctl reread
sudo supervisorctl add hello
sudo supervisorctl start hello

You can check the status and stop the hello app with sudo supervisorctl status

Now you can close the terminal and grab your coffee.

And anyone can open http://YourDomainOrIP/hello in their browser, it should show the message “hello world”.

Recommended readings:

I have tried to keep the article short and simple. Here’s a list of recommended readings if you are not already familiar with Nginx, Tmux etc.

  1. Initial server setup guide for Ubuntu 16.04
  2. Install and setup Nginx
  3. Tmux: Easy guide

Other interesting things you can try:

  1. Setup a domain name on Digitalocean
  2. Setup postgres with Vapor 2
  3. Run multiple Vapor Apps on a single instance