/ Tutorial

How to run Swift on linux

Learn how to make the perfect server using Swift, under Ubuntu linux running on Amazon EC2, Heroku, Docker or a VirtualBox machine.


Setting up the environment

Developing server side Swift applications is pretty easy if you have a machine that is capable of virtualization. However you can go and start building Swift apps directly on Amazon Elastic Compute Cloud (EC2) or Heroku services if you don't want to bloat your machine with tools like Docker or VirtualBox.

TL;DR: grab the configured Kitura 2.0 example server application from github.

Docker

Docker

Containerization is extremely popular nowadays and Docker is definitely the top player on the market. In the past people told you there is an app for that, nowadays devops will always tell you:

there is a container for that

This is absolutely true, there is a Swift container which you can use out of the box, you just have to install the Docker app, which it's possible through homebrew's cask.

brew cask install docker

# if you want completions run these commands as well
brew install bash-completion
brew install docker-completion
brew install docker-compose-completion
brew install docker-machine-completion

Now run the Docker app. Give the required privileges and wait until docker boots on your system. Congratulations you're ready to compose. Just create a docker-compose.yaml file with the following contents:

ubuntu-swift:
  image: swiftdocker/swift
  volumes:
    - .:/app

Run the docker-compose command with these arguments:

docker-compose run ubuntu-swift bash
# wait until everything finishes and check Swift version
root@c031a74aa0f1:/# swift --version
Swift version 4.0.2 (swift-4.0.2-RELEASE)
Target: x86_64-unknown-linux-gnu

Voila, your virtual linux machine is up and running, ready to compile your source code. You can edit your files on macOS while you can compile everything inside your virtual docker machine. Your directory will be mounted under the /app path.

Heroku

Heroku

There is a Heroku buildback for Swift that you can use to deploy Swift apps.
Just sign up for Heroku and install the command line tools on your machine.

brew install heroku/brew/heroku

After you have the cli tools, use the buildpack to create a new app.

heroku create --buildpack https://github.com/kylef/heroku-buildpack-swift.git

Enter your Heroku credentials and the script will make you a brand new Swift application on the server. Now you should create a .swift-version file with the contents of 4.0, and a Procfile inside your project directory.

web: KituraTutorial --workers 1 --bind 0.0.0.0:$PORT

Now init a git repository with git init and setup the heroku remote. You can see the details on your application page inside the Heroku dashboard.

heroku git:remote -a your-heroku-app-name

Just commit and push everything from the master to the Heroku remote.

git push heroku master

If something fails, you can enter heroku logs to see what's going on, but hopefully your server will be up and running if you followed these instructions.

VirtualBox

VirtualBox

Playing around with server side Swift takes a little bit more effort than using a Docker container. First, you should install the VirtualBox app.

brew cask install virtualbox

Next you have to create your virtual machine and manually install a working operating system - usually a Ubuntu Linux 16.04 LTS - on top of that. You should grab the minimal ubuntu installer image, mount that and follow the instructions.

Swift-Ubuntu-VirtualBox-machine

NOTE: During the install process the partition manager wants to create lots of swap area, so you should double check if your partition sizes are correct, you should give at least 8gigs for the main drive, but I'd go with 16GB.

Anyway, I assume that you made it so far, so it's time to install some tools on the guest machine. Run the following commands inside your VirtualBox instance.

sudo apt-get install virtualbox-guest-additions-iso
sudo apt-get install openssh-server

Setup port forwarding to reach your virtual machine easier. Stop the machine, unomunt or even completely eliminate the 'optical' the ubuntu installer disk. Now go to the network settings of the virtual machine.

Swift-Ubuntu-Virtualbox-network

Click port forwarding, and create a new rule. You can set any kind of host port you want, only the guest port matters. We would like to forward the ssh (22) port via TCP protocol, you can leave the IP fields empty. So basically this will allow you to ssh to your virtual machine from your local machine.

Swift-Ubuntu-Virtualbox-port-forward

On your host machine, generate a new key-pair.

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Start the virtual machine and SSH into it using your user account and your password.

ssh -p 3022 ubuntu@127.0.0.1

Hopefully now you are inside your virtual machine through ssh. The thing is that I don't really prefer passwords. So go to your home folder, make an .ssh folder and place an authorized_keys file inside of it.

cd
mkdir .ssh
nano authorized_keys

Start a new terminal window/tab. List your vbox.pub file contents on your mac, and copy it's content to the authorized_keys file on the virtual machine. If you used nano you can save by ctrl+x and then pressing the y key and return.

cat ~/.ssh/vbox.pub 

Now create or add the following lines to your ~/.ssh/config file on your host / mac.

Host            vbox
HostName        127.0.0.1
Port            3022
User            ubuntu
IdentityFile    ~/.ssh/vbox

Obviously you should use your ubuntu linux username here.
Congratulations you can simply ssh to virtual machine like this:

ssh vbox

No more password typing again and again. You can even control your VirtualBox machine from the command line, with these really useful bash aliases.

alias vbox.start='VBoxManage startvm "ubuntu" --type headless'
alias vbox.stop='VBoxManage controlvm "ubuntu" savestate'

Now, you have a bare minimal VirtualBox ubuntu instance with key based ssh authentication, but you still need to install Swift and move the files to the virtual machine in order to make some actual work. As you can see setting up Docker is way more easy and resource friendly so I'd recommend goint with that way.

Before I teach you how to install Swift 4 and syncronize your source files to your instance, let's talk a little bit about Amazon EC2.

aws

Amazon EC2

You should follow the Amazon Web Services User Guide about how to start an EC2 instance, that'll give you a really basic running machine with linux and an ssh key for the root user that you can use to access your machine.

Creating a new instance is a really easy process, you just have to follow the wizard, but you should note that this won't result as a good production environment.

In the end you'll have an ssh key which you can use to log in to your server, just like we made one for the VirtualBox instance. Don't forget to set up your ssh config file to make your life more pleasant. The only difference is that the EC2 server is "in the cloud", this means you can scale it up and do some other neat things with it.

Now, you are ready to install Swift on Amazon EC2 or on your VirtualBox machine.

Swift-1

Installing Swift

swift.org-download

  • Go to swift.org/download
  • Right click on the ubuntu installer link, and copy the url.
  • Use wget or curl to download the swift snapshot to your home folder.
  • Use tar -xf swift.tar.gz* to unpack the file.
  • Rename the extracted folder simply to swift
  • Add the following path component to /etc/environment (use your username)
PATH="-original-path-here-:/home/ubuntu/swift/usr/bin"
  • Re-ssh to your virtual box machine.
  • Try the swift --version command.
  • Install some extra packages that you'll need
sudo apt-get install clang libicu-dev libcurl3

icloud

Code syncing

You can simply syncronize all your sources into a remote server with the help of the rsync command, so you can continue using your favorite editor on the host machine. You can also write a simple makefile and bind the process to your editor's build command. This build script will transfer all the local source files to the remote machine's ~/linux folder, it'll also exclude some local directories.

all:
	rsync -avzh --progress --exclude=".*" --delete-before ./ vbox:/home/ubuntu/linux

NOTE: I am using Sublime Text, because I just have to press cmd+b to sync everything. Also I always keep an open terminal window with an ssh login to the client, so I can build & run the sources instantly.

External sources