Deploy your Swift on the Server apps with Kamal 2
In this blog post, you'll learn how to use Kamal 2 to deploy your Swift on the Server apps to your own server.
Swift is an amazing language. Developers use it not only for building apps for Apple platforms, but also to run them on the browser or embedded systems. One of the platforms where developers were very excited to run Swift was the server. This excitement led to the creation of frameworks like Vapor and Hummingbird, a conference, and even Apple evolved the language to introduce features that are key in building highly-concurrent web applications, like structured concurrency and Actors. Did you know that the team behind Things uses it for server?
If you are new to using Swift on the server, one of the things you’ll have to figure out is how to and where deploy your app. Historically, there has been many options to deploy your app. Some large-scale organizations resorted to tools like Kubernetes, which provided them with a lot of flexibility to deploy, scale, and manage their apps, and an independence from cloud providers. However, Kubernetes is not the easiest tool to use. So if you are a solo developer or a small team, you might want to look for something simpler.
You could always get your own server, SSH into it, and manually set things up there, but you want a system that is able to roll new versions out automatically ensuring there’s no downtime. This would be hard to achieve through a manual configuration.
Simpler and an automatic alternative those models were using platforms like Heroku or Fly that made it easy to deploy your app.
They made it as easy as running a git push
or fly deploy
command against them server.
Those platforms are often referred to as PaaS (Platform as a Service).
Their developer experience is top-notch, but since they sit between you and the infrastructure,
you might have to pay an extra cost for the convenience they provide.
What if the great DX could be achieved without that extra cost?
That’s the question that the Basecamp Team,
in their process of moving away from the cloud,
asked themselves when they created Kamal.
They started referring to it as #nopaas.
What is Kamal?
Kamal is a Ruby-based CLI,
that can deploy containarized applications to your own SSH-accessible server.
All you need is an OCI-compliant (e.g. in a Dockerfile
),
a registry to push and pull the image from,
and a server what can be accessed through SSH.
Kamal will take care of the rest with an intuitive and well thought-out CLI.
Don’t let the Ruby part scare you. You don’t need to know Ruby to use Kamal. All the configuration is done through a very intuitive YAML-based configuration file.
In this post, we’d like to guide you through the process of deploying a Swift on the Server app using Kamal to an infrastructure provider like Hertzner.
Installing Kamal
The first thing you’ll need to do is to install Kamal.
If you have a Ruby setup already, for example to run Fastlane,
you can use Ruby’s gem install kamal
command to install it.
Alternatively, as suggested in the documentation,
you can run it through a container, which eliminates the need to have Ruby installed on your machine:
Create a server on Hetzner
If you don’t have a server yet, you can can create one on Hetzner or any other provider that gives you SSH access.
When you create a server, you’ll be asked for the following information:
-
Location: This will depend on where most of the request to your app will come from. In our case, we are going to select
eu-central
for the sake of this tutorial. - Image: Select Ubuntu 20.04, although Kamal should work with other Linux distributions.
- CPU: Select the smallest one from either x86 or ARM64, which is enough for a small app.
- Networking: Select Public IPv6. Later on you can add a Public IPv4 if you need.
- SSH keys: This is a very important part since it will allow you to access the server. If you don’t have an SSH key yet, you can generate one following this tutorial.
There are a handful of other options, from which we recommend you to enable backups in case you need to restore the server.
Then scroll down to the bottom, give it a name, which in our case will be swift-on-server
, and click on Create & Buy Now
.
In a few seconds you’ll have your server up and running with the IP addres to access to it.
Make sure you can access to it by running:
Create a Swift on the Server app
If you don’t have a Swift on the Server app yet, you’ll need to create one. You can follow either this tutorial if you plan to use Vapor, or this other one if you plan to use Hummingbird.
Note that projects created by both frameworks include a Dockerfile
(Hummingbird and Vapor) to build and run your apps.
This is a requirement for Kamal, so if your project doesn’t have one, you’ll need to create it using those as a reference.
To make sure your app runs fine when containerized, you can run it locally:
If those commands succeed, you should see a log indicating that the app is running in some port.
Adding Kamal configuration
Once you have Kamal installed, a containarizable Swift on the Server app, and a server to deploy it to, you can start adding the Kamal configuration.
Create the file config/deploy.yml
in your project with the following content:
You’ll have to create a file at .kamal/secrets
with the following content to indicate the environment variables that Kamal will use to read the registry credentials:
By default, Kamal will use the hub.docker.com registry to push and pull the image,
which is free for public images.
GitHub and DigitalOcean also offer registries, so you can use them if you prefer ensuring that you set the registry.server
URL in the configuration file.
Once you have the configuration file in place, you can run the following command to set up the server and accessories:
Once the server is setup, you can deploy your app by running:
Once the app is deployed, you can access it by visiting the IP address of the server in your browser.
Remember that for IPv6 addresses, you’ll have to wrap them in square brackets. For example: http://[2a01:4f8:c013:44ae::1]
.
Isn’t it awesome? 🤩 With a single command you can deploy new instances of your app without any downtime.
And not only that, you can use kamal rollback
to roll back to a previeous version in case something goes wrong,
or kamal app logs
to see the logs of the app in real-time.
Bonus
As a natural next step, you might want to set up a domain to point to the IP address of the server,
and configure the Kamal proxy to provide HTTPs automatically for your app.
For the latter, all you need to do is to add the following lines to the config/deploy.yml
file:
With the above configuration, Kamal will automatically request a certificate from Let’s Encrypt and configure the proxy to serve your app through HTTPs.
Closing words
At Tuist we love simplicity and automation, and we believe that Kamal embodies that spirit for deployments. When you are getting started, or even if you are at the size of a company like 37Signals, the company behind Kamal, you might want to keep your infrastructure engineering and financial costs low without compromising the developer experience. We belive Kamal is unique in striking that balance, and can help you stay focused on what you do best: building your Swift on the Server app.
Until next time 🚀