Run a server-side Swift app using Perfect framework trough Nginx/Supervisor on Ubuntu 16.04

The steps describe how to setup and run a web app using Perfect framework on an existing Ubuntu 16.04 web server. (the web app will run on the same server using a different port).

Download and install Swift:

wget https://swift.org/builds/swift-3.1.1-release/ubuntu1604/swift-3.1.1-RELEASE/swift-3.1.1-RELEASE-ubuntu16.04.tar.gz  
tar xzf swift-3.1.1-RELEASE-ubuntu16.04.tar.gz  
sudo mv swift-3.1.1-RELEASE-ubuntu16.04 /usr/local  
rm swift-3.1.1-RELEASE-ubuntu16.04.tar.gz  

Install required dependences:

sudo apt install clang libicu-dev  
sudo apt-get install libcurl3  
sudo apt-get install libsqlite3-dev  
sudo apt-get install uuid-dev  

Add Swift to system PATH:

echo 'export PATH=/usr/local/swift-3.1.1-RELEASE-ubuntu16.04/usr/bin:$PATH' ~/.profile  
source .profile  

I assume you've created your app (eg. webapp) ... If you haven't, below is a 'Hello world' main.swift:

import Foundation  
import PerfectLib  
import PerfectHTTP  
import PerfectHTTPServer

let server = HTTPServer()  
var routes = Routes()  
routes.add(method: .get, uri: "/", handler: {  
   request, response in
   response.appendBody(string: 'Hello world!')
   response.completed()
})
server.addRoutes(routes) // Add the routes to the server  
server.serverPort = 8181 // Set a listen port of 8181  
// Launch the HTTP server
do {  
   try server.start()
} catch PerfectError.networkError(let error, let msg) {
   print("Network error thrown: \(error) \(msg)")
}

Copy app directory to a directory on the server (eg. to /var/www/webapp). To compile and test the app:

cd /var/www/webapp  
swift build -c release  
./.build/release/webapp

Install supervisor

apt-get install -y supervisor  

To setup app running through Supervisor, create:

/etc/supervisor/conf.d/webapp.conf
[program:webapp]
command = /var/www/webapp/.build/release/webapp serve --ip=127.0.0.1 --port=8181  
directory = /var/www/webapp/  
user=www-data  
autostart = true  
autorestart = true  
stdout_logfile = /var/log/supervisor/%(program_name)-stdout.log  
stderr_logfile = /var/log/supervisor/%(program_name)-stderr.log  

Append following to your nginx configuration:

location ~ ^/webapp(/?)(.*)$ {  
    alias /var/www/webapp;

    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;
    proxy_pass         http://127.0.0.1:8181/$2$is_args$args;
}

Restart nginx

service nginx restart  

Register the app with Supervisor:

supervisorctl reread  
supervisorctl add webapp  

Visit:

http://yourserver.com/webapp  

To start/stop app:

supervisorctl start webapp  
supervisorctl stop webapp  

In case if anything goes wrong...

/var/log/supervisor/webapp-stdout.log
/var/log/supervisor/webapp-stderr.log
/var/log/nginx/access.log;
/var/log/nginx/error.log;

Swift
Perfect
Getting started with Swift 3 on Linux
Deploying Vapor example