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:

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!')
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  

Install supervisor

apt-get install -y supervisor  

To setup app running through Supervisor, create:

command = /var/www/webapp/.build/release/webapp serve --ip= --port=8181  
directory = /var/www/webapp/  
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;

Restart nginx

service nginx restart  

Register the app with Supervisor:

supervisorctl reread  
supervisorctl add webapp  


To start/stop app:

supervisorctl start webapp  
supervisorctl stop webapp  

In case if anything goes wrong...


Getting started with Swift 3 on Linux
Deploying Vapor example